Parsing the Page - javascript

I wrote a small js script, I want to enter the site by login and password and parsing data birthday and name users on the page I need. But i do not know what i need to do further
var page = require('webpage').create();
phantom.cookiesEnabled = true;
page.open("http://www.facebook.com/login.php", function(status) {
if (status === "success") {
page.evaluate(function() {
document.getElementById("email").value = "login#mail.com";
document.getElementById("pass").value = "12345";
document.getElementById("u_0_1").click();
});
window.setTimeout(function() {
page.render("fb.png");
}, 5000);
page.open('https://www.facebook.com/friends/requests/?fcref=ff', function() {
window.setTimeout(function() {
page.render("fb2.png");
phantom.exit();
}, 5000);
});
}
});

Related

Javascript - confirmation dialog after form submission

I am not a Javascript wiz so need some help with the following. I have a popup asking people to type in their email address. Right now the popup just closes after submission, which isn't a nice user experience. Ideally the text bar and the submission button would disappear, and be replaced by a short comment such as "Thanks, we'll be in touch". Even better would be if the popup would then disappear after "N" seconds.
Can anyone help?
var self = this;
var showDelay = parseInt('[[ bannerShowDelayInMilliseconds ]]' || '0', 10);
setTimeout(function () {
requestAnimationFrame(function () {
if (!self.inPreview && "true" == "{{ 'true' if customer.email else 'false' }}") {
return;
}
self.sdk.track('banner', getEventProperties('show', false));
document.body.insertAdjacentHTML('beforeend', self.html);
var banner = self.banner = document.querySelector('.exponea-subscription-dialog');
self.backdrop = document.querySelector('.exponea-subscription-dialog + .exponea-banner-backdrop');
banner.insertAdjacentHTML('afterbegin', '<style>' + self.style + '</style>');
var form = banner.querySelector('form');
form.onsubmit = function () {
var eventProperties = getEventProperties('subscribe');
var email = (form.email.value || '').toLowerCase();
eventProperties.subscription_email = email;
self.sdk.track('banner', eventProperties);
if (validateEmail(email)) {
self.sdk.update({
email: email
});
document.getElementById("dialogue").innerHTML = "Thank you message";
setTimeout(function(){ removeBanner(); }, 3000);
}
return false;
};
var btnClose = banner.querySelector('.exponea-close');
btnClose.onclick = function () {
removeBanner();
self.sdk.track('banner', getEventProperties('close'));
};
});
}, showDelay);
function getEventProperties(action, interactive) {
return {
action: action,
banner_id: self.data.banner_id,
banner_name: self.data.banner_name,
banner_type: self.data.banner_type,
variant_id: self.data.variant_id,
variant_name: self.data.variant_name,
interaction: interactive !== false ? true : false,
location: window.location.href,
path: window.location.pathname
};
}
function removeBanner() {
if (self.banner) {
self.banner.parentNode.removeChild(self.banner);
}
if (self.backdrop) {
self.backdrop.parentNode.removeChild(self.backdrop);
}
}
function validateEmail(email) {
return email && /^\S+#\S+\.\S+$/.test(email);
}
return {
remove: removeBanner
};
form.onsubmit = function () {
var eventProperties = getEventProperties('subscribe');
var email = (form.email.value || '').toLowerCase();
eventProperties.subscription_email = email;
self.sdk.track('banner', eventProperties);
if (validateEmail(email)) {
self.sdk.update({
email: email
});
document.getElementById("thankYouIdExample").innerHTML = "Thank you message";
setTimeout(function(){ removeBanner(); }, 3000);
}
return false;
Just make sure to place the <div id="thankYouIdExample"></div> at the right place.
Let me know if it works for you m8
You can insert your thanks message in another container, and write something like this:
<div id="container">
<div id="form">
here is the form and everything that belongs here
</div>
<div id="thanks">
here is the thanks message
</div>
</div>
With this, you can set the default style of the thanks div to display: none; in css.
If you reference the container divs in js by their ids, you can change their style from js. The setTimeout() method can be used to time the closing of the dialog box, assuming it is done by the removeBanner() function. You can add these lines:
form.onsubmit = function () {
var eventProperties = getEventProperties('subscribe');
var email = (form.email.value || '').toLowerCase();
eventProperties.subscription_email = email;
self.sdk.track('banner', eventProperties);
if (validateEmail(email)) {
self.sdk.update({
email: email
});
document.getElementById("form").style.display = 'none';
document.getElementById("thanks").style.display = 'block';
setTimeout(function(){removeBanner();}, 5000);
}
return false;
This way you can have a fully pre-customized thanks message.
Use setTimeout
https://www.w3schools.com/jsref/met_win_settimeout.asp
https://developer.mozilla.org/de/docs/Web/API/WindowTimers/setTimeout
form.onsubmit = function() {
var eventProperties = getEventProperties('subscribe')
var email = (form.email.value || '').toLowerCase()
eventProperties.subscription_email = email
self.sdk.track('banner', eventProperties)
if(validateEmail(email)) {
self.sdk.update({
email: email
})
setTimeout(() => {
alert("Thatnk You") // you may want to replace it with a own dialogue system
removeBanner()
}, 5000) // wait 5000 milliseconds or in other words 5 seconds
}
return false
}
Asynchronous version (if you want to return after the 5000 wait):
*only useful if you not directly call the handler
form.onsubmit = async function() {
return Promise((resolve, reject) => {
var eventProperties = getEventProperties('subscribe')
var email = (form.email.value || '').toLowerCase()
eventProperties.subscription_email = email
self.sdk.track('banner', eventProperties)
if(validateEmail(email)) {
self.sdk.update({
email: email
})
setTimeout(() => {
alert("Thatnk You") // you may want to replace it with a own dialogue system
removeBanner()
resolve()
}, 5000) // wait 5000 milliseconds or in other words 5 seconds
}
else reject()
})
}

Is there any security flaw in using iframe as a communication layer cross site?

Goal of this poc:
a way to keep the user logged in across webapps
on different domains
do it once, import it everywhere
The poc:
So I thought of this possible solution. I call it the user widget.
Let's say we have service AUTH that provides the endpoint to login and logout, it also sets the httpOnly cookie.
This should be the header, distributed across webapps. The header downloads the iframe and with postMessage send calls to it, to understand if the user is already logged in, otherwise shows login:
<script>
/**
****************************************
* Code that should be inside the header
****************************************
*/
window.onload = function() {
(function(){
if (window.addEventListener) {
window.addEventListener("message", handleMessage, false);
} else {
window.attachEvent("onmessage", handleMessage);
}
//- This could be * meaning no preferences, or a URI,
//- but SHOULD not be * but the correct origin
var iframeOrigin = "*";
var iframeId = 'IFRAME-PROXY';
createIframe(checkStatusOfLogin);
var doLoginButton = document.getElementById('do-login');
doLoginButton.onclick = doLogin;
function createIframe(onLoadCallback) {
var iframe = document.createElement('iframe');
iframe.id = iframeId;
iframe.style.display = 'none';
iframe.src = 'https://mysecureiframe.securedomain.com/file.html';
document.body.appendChild(iframe);
iframe.onload = function () {
onLoadCallback(iframe);
};
}
function checkStatusOfLogin(iframe) {
var iframeWin = iframe.contentWindow;
var payload = {
action: 'status'
};
iframeWin.postMessage(JSON.stringify(payload), iframeOrigin);
}
function doLogin() {
var iframeWin = document.getElementById(iframeId).contentWindow;
var payload = {
action: 'login',
username: document.getElementById('username').value,
password: document.getElementById('password').value
};
iframeWin.postMessage(JSON.stringify(payload), iframeOrigin);
}
function handleMessage(evt) {
console.log('Inside client tab, received: ', evt);
var userContainer = document.getElementById('user-container');
try {
var parsedResponse = JSON.parse(evt.data);
if (parsedResponse.isCIA) { // checking it's a postmessage from us and not an extension
if (parsedResponse.status == "LOGGED_IN") {
userContainer.classList.remove('not-logged-in');
} else if (parsedResponse.status == 'NEED_LOGIN') {
userContainer.classList.add('not-logged-in');
}
} else {
throw new Error('not CIA message');
}
} catch (e) {
console.log('not CIA message');
}
}
}());
};
/**
*******************
* End of header code
* *****************
*/
</script>
The iframe contains a really simple body:
<!DOCTYPE html>
<html>
<head>
<script src="https://mysecureiframe.securedomain.com/loginProvider.js" type="text/javascript" ></script>
</head>
<body>
<p>IFRAME NON VISIBILE</p>
</body>
</html>
And here's the content of loginProvider.js:
(function() {
if (window.addEventListener) {
window.addEventListener("message", handleMessage, false);
} else {
window.attachEvent("onmessage", handleMessage);
}
// to read: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
// Guardare HEADER Content-Security-Policy instead of X FRame Options
function checkStatus(success, failure) {
var http = new XMLHttpRequest();
var url = "https://mysecureiframe.securedomain.com/status"; // AUTH endpoint
http.open("GET", url, true);
http.onreadystatechange = function() { //Call a function when the state changes.
if (http.readyState == 4 && http.status == 200) {
if (http.responseText == "true") {
success();
} else {
failure();
}
}
};
http.send();
}
function doLoginIframe(user, pass) {
var http = new XMLHttpRequest();
var url = "https://mysecureiframe.securedomain.com/login"; // AUTH endpoint
http.open("POST", url, true);
http.onreadystatechange = function() { //Call a function when the state changes.
if (http.readyState == 4 && http.status == 200) {
if (user == 'username' && pass == 'password') {
var payload = getPayload();
payload.status = 'LOGGED_IN';
parent.postMessage(JSON.stringify(payload), "http://targetOrigin");
alert(http.responseText);
}
}
};
http.send();
}
function getPayload() {
return {
isCIA: true
};
}
function handleMessage(evt) {
console.log('Inside iframe, got: ', evt); // TODO Check targetOrigin is from trusted sites
var parsedRequest = JSON.parse(evt.data);
if (parsedRequest.action == "status") {
checkStatus(function() {
var payload = getPayload();
payload.status = 'LOGGED_IN';
parent.postMessage(JSON.stringify(payload), "http://targetOrigin");
},
function () {
var payload = getPayload();
payload.status = 'NEED_LOGIN';
parent.postMessage(JSON.stringify(payload), "http://targetOrigin");
});
} else if (parsedRequest.action == "login") {
doLoginIframe(parsedRequest.username, parsedRequest.password);
}
}
}());
Besides adding the check to see if origin is a trusted site, do you see particular security flows with this strategy?

What is the right syntax for injecting Javascript with PhantomJS?

My goal is to inject:
javascript document.getElementById("pickupZip").value = "90049";
document.getElementById("refreshStoresForZipPop").click();
into a website with PhantomJS. This is all of the code on my inject.js file, and I get this in the console: SyntaxError: Expected an identifier but found "document" instead, so I know it is the wrong syntax, though I can't find a place that shows what the correct is. Here is my code for the PhantomJS file:
var webPage = require('webpage');
var page = webPage.create();
page.open('http://shop.advanceautoparts.com/p/purolator-classic-air-filter-a24278/5792304-P?navigationPath=L1*14934/', function(status) {
var success = phantom.injectJs('inject.js');
console.log(success);
if (status === "success") {
page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {
page.render('advanceautoparts.png');
phantom.exit();
});
}
});
Use evaluate.
var webPage = require('webpage');
var page = webPage.create();
page.open('http://shop.advanceautoparts.com/p/purolator-classic-air-filter-a24278/5792304-P?navigationPath=L1*14934/', function(status) {
var success = phantom.injectJs('inject.js');
console.log(success);
if (status === "success") {
page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {
page.evaluate(function(s) {
document.getElementById("pickupZip").value = "90049";
document.getElementById("refreshStoresForZipPop").click();
});
page.render('advanceautoparts.png');
phantom.exit();
});
}
});
Reference: http://phantomjs.org/api/webpage/method/evaluate.html

Prevent users from opening multiple instance of same website PHP

I need only one tab accessible for my website. When he tries to open in new tab or even tries to copy and paste the url in new tab should clear the user's session and logout from the application.
There are several reasons,
When a user opens a new tab connecting to the same application - the session id is the same.
Imagine that this user has reached a page X in the application flow from the first tab.
When he opens the second tab he might be in one of the following scenarios - depending how the second tab was opened - new tab, duplicate tab (this copies the URL to the newly opened tab), or new session.
All of the above will "confuse" the server as to what the next valid state of the application is, and could override data entered in different tab, without his/her knowledge
What I want is to prevent a single user to have several tabs in the same session, i.e. only one tab/window per user, per session.
Including the below script in dashboard.php after login
<script>
$(document).ready(function()
{
if(typeof(Storage) !== "undefined")
{
if (sessionStorage.pagecount)
{
sessionStorage.removeItem('pagecount');
window.location='logout.php';
}
else
{
sessionStorage.pagecount = 1;
}
}
else
{
sessionStorage.removeItem('pagecount');
window.location='logout.php';
}
});
Below code in other sub pages in the application
<script>
$(document).ready(function()
{
if(typeof(Storage) !== "undefined")
{
if (sessionStorage.pagecount)
{
sessionStorage.pagecount = Number(sessionStorage.pagecount) + 1;
}
else
{
sessionStorage.removeItem('pagecount');
window.location='logout.php';
}
}
else
{
sessionStorage.removeItem('pagecount');
window.location='logout.php';
}
});
</script>
Added the below script after I login(say dashboard.php)
<script>
$(document).ready(function()
{
$("a").attr("target", "");
if(typeof(Storage) !== "undefined")
{
sessionStorage.pagecount = 1;
var randomVal = Math.floor((Math.random() * 10000000) + 1);
window.name = randomVal;
var url = "url to update the value in db(say random_value)";
$.post(url, function (data, url)
{
});
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
});
</script>
Added the below script in Header in rest of my pages - 'random_value' is from db for that user
<script>
$(document).ready(function()
{
$("a").attr("target", "_self");
if(typeof(Storage) !== "undefined")
{
if (sessionStorage.pagecount)
{
if('<?=$random_value?>' == window.name)
{
sessionStorage.pagecount = Number(sessionStorage.pagecount) + 1;
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
});
</script>
<script>
$(document).ready(function()
{
$("a").attr("target", "");
if(typeof(Storage) !== "undefined")
{
sessionStorage.pagecount = 1;
var randomVal = Math.floor((Math.random() * 10000000) + 1);
window.name = randomVal;
var url = "url to update the value in db(say random_value)";
$.post(url, function (data, url)
{
});
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
});
</script>

How to display popup only for first login

I am implementing login with facebook using javascript SDK.
Now in my code i have 3 different JS files
1. content.js and 2. FacebookLogin.js 3. popup.js
In my code there is anchor tag and onclick action opens a popup with different login options like facebook, linkedin, googleplus, twitter. Among them I have integrated for facebook.
Now once i click on facebook, iFrame opens and asks for login creds, then i supplies those and able to login properly.
Now user is logged in and I dont want to display that popup again on click of anchor tag. This means I want it to display only when user is not logged in.
Once the user is logged in and if i click on that link it should not open up that popup.
CODE:
content.js
function includeScripts(){
var head = document.getElementsByTagName('head')[0];
var host = "192.168.1.6";
var server = "http://" + host + ":8080/OtherDomain/";
// load Popup.js
var popupJs = document.createElement("script");
popupJs.type = 'text/javascript';
popupJs.src = server + "js/Popup.js?_=" + new Date();
head.appendChild(popupJs);
// load FacebookLogin.js
var facebookJs = document.createElement("script");
facebookJs.type = 'text/javascript';
facebookJs.src = server + "js/FacebookLogin.js?_=" + new Date();
head.appendChild(facebookJs);
// load GooglePlusLogin.js
var googlePlusJs = document.createElement("script");
googlePlusJs.type = 'text/javascript';
googlePlusJs.src = server + "js/GooglePlusLogin.js?_=" + new Date();
head.appendChild(googlePlusJs);
var styleSheet = document.createElement('link');
styleSheet.href = server + 'css/mpw.css?' + new Date();
styleSheet.rel = "stylesheet";
head.appendChild(styleSheet);
}
function onClickLoginPopup (e) {
e.preventDefault();
var url = this.href;
var guid = this.attributes.getNamedItem("GUID");
var mainPopup = document.getElementById('popupMain');
if( mainPopup == null ) {
console.log(mainPopup);
}
else
{
showSocialLoginPopup();
}
return false;
}
function addClickEventListenerToAllAnchorTag() {
var anchors = document.getElementsByTagName("a");
for(var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
var guid = anchor.attributes.getNamedItem('GUID');
if(guid)
{
anchor.addEventListener("click", onClickLoginPopup);
}
}
}
function mpwInit() {
addPopupContents();
addClickEventListenerToAllAnchorTag();
}
includeScripts();
window.onload = mpwInit;
This is the facebook javascript:
// This is called with the results from from FB.getLoginStatus().
function statusChangeCallback(response)
{
console.log('statusChangeCallback');
console.log(response);
if (response.status === 'connected')
{
// Logged into your app and Facebook.
}
else if (response.status === 'not_authorized')
{
// The person is logged into Facebook, but not your app.
//alert(response.status + "Please log into this app");
document.getElementById('status').innerHTML = 'Please log ' +
'into this app.';
}
else
{
// The person is not logged into Facebook, so we're not sure if
// they are logged into this app or not.
// alert(response.status + "Please log into Facebook");
document.getElementById('status').innerHTML = 'Please log ' +
'into Facebook.';
}
}
// This function is called when someone finishes with the Login
// Button. See the onlogin handler attached to it in the sample
// code below.
function checkLoginState()
{
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
window.fbAsyncInit = function()
{
FB.init({
appId : 'MY_APP_ID',
cookie : true, // enable cookies to allow the server to access
// the session
xfbml : true, // parse social plugins on this page
version : 'v2.2' // use version 2.2
});
FB.getLoginStatus(function(response)
{
statusChangeCallback(response);
});
};
function Logout()
{
FB.logout(function(){document.location.reload();});
}
function fblogin()
{
FB.login(function(response){
console.log('FB.login response',response);
checkLoginState();
});
return false;
}
// Load the SDK asynchronously
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
My popup.js code:
function showSocialLoginPopup() {
document.getElementById('popupMain').style.display = 'block';
}
function hidePopup() {
document.getElementById('popupMain').style.display = 'none';
}
function addPopupContents() {
var mainPopup = document.getElementById('popupMain');
if (mainPopup == null ) {
var xmlhttp;
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.body.innerHTML += xmlhttp.response;
}
};
xmlhttp.open("GET", 'http://192.168.1.6:8080/OtherDomain/popup.html', false);
xmlhttp.send(null);
}
}
// To detect escape button
document.onkeydown = function(evt) {
evt = evt || window.event;
if (evt.keyCode == 27) {
hidePopup();
}
};
Please help
That´s what getLoginStatus is for, to check if the user is already autzorized and to refresh the user session/token. You should only use it on page load (right after FB.init) and just store the status (or the User ID) in a JS variable. Example code is in the docs.
For example:
var userID;
window.fbAsyncInit = function()
{
FB.init({
...
});
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
//user is authorized
userID = response.authResponse.userID;
} else {
document.getElementById('status').innerHTML = 'Please log into Facebook.';
}
});
};
Here´s an article about the whole login process:
http://www.devils-heaven.com/facebook-javascript-sdk-login/
You can add a local variable to Browsers Storage and check its value before displaying your Login-Dialog.
// Store
localStorage.setItem("loggedIn", "1");
//Retrieve
var value = localStorage.getItem("loggedIn");
If your User needs to relogin everytime the Browsers closes, than i would use sessionStorage instead.

Categories