How to log out showing the proper status? - javascript

I have a members site. Every web page's header bar will have the following 2 options depending the user is logged in or not:
Option 1) if the user is logged in, it will have the following 2 links:
"user12345"
"logout"
Option 2) if the user is log out, above 2 links will become:
"login"
"register"
The page has some Javascript code which will check a user cookie. If the user cookie exists, if will display option 1), otherwise option 2). There is no problem with the Javascript. It shows above options correctly.
Here's the problem. I use a server side script (perl) to do the "logout" function. The script will delete the cookie and re-direct back to the original page. I am hoping the page will show option 2), but it doesn't. It still shows option 1). The page needs to be refreshed to show option 2). This is confusing because users have clicked the logout link, yet when they return to the page, they still see their usernames there. They need to refresh the web browser in order to see that they have logged out.
Option 2) should show on the page upon clicking the "logout" link. But I simply have no idea how to get this done successfully.
Please provide your expertise to fix this problem.

First, I would suggest breaking the problem down so that you can test the logout functionality separate from the page redirect.
Modify your Perl script so logout doesn't redirect.
Login and then click logout.
Use a Chrome or Firefox extension that lets you view cookies. Verify that the cookie has been deleted.
If everything checks out here, I would suggest that you then reconnect the redirect and repeat the above steps:
When your page redirects and you don't see the login | register buttons, check to see if the cookie was deleted, if the cookie appears, then there may be something being cached in the code after the redirect.
As an alternative, you could use the document.referrer to capture your logout URL in your JavaScript code and also use this to determine if you should show the login | register buttons. For instance:
if(document.referrer = "/logout" || /* existing check of cookie goes here */) {
// show login | register
} else {
// show username, etc.
}
If possible, the best solution usability-wise would be to turn your logout url into an AJAX call so you don't need to reload the page. This would be better than the above solution because you could check the response object to determine if the logout operation was a success. If so, you could then dynamically replace the header bar with the correct text.
An AJAX example, using jQuery.ajax, is as follows:
$.ajax({
url: '/logout',
success: function(data) {
if(data.logout == true) {
// user is logged out
}
},
error: function(jqXHR, textStatus, errorThrown) {
/* problem with logout */
}
});
Your perl logout script will need to return a JSON object as a String, if successful:
{"logout":true}
There are other ways of making AJAX calls and transferring data to/from the server, and you can find those examples doing a search on Stackoverflow for "AJAX".

BlockquoteFirst, I would suggest breaking the problem down so that you can test the logout functionality separate from the page redirect...
I've fixed the problem without the use of AJAX call.

Related

location.replace() doesn't replace the page

I'm experimenting for the first time with transition between html pages. I've been looking for the differences between replace and a href when I founded them I chose the second one. I'm building a sign-out button. So when i click on it I need to be redirected to the login page. But I also need to make impossible for the user to navigate back to the home (from the login) with the back button. So in my home.js file I wrote that (I'am working with firebase):
const disconnettitiButton = document.getElementById("disconnettiti");
disconnettitiButton.addEventListener('click', () => {
firebase.auth().signOut().then(function() {
// Sign-out successful.
window.location.replace("../index.html");
}).catch(function(error) {
// An error happened.
});
});
while this is the html corresponding to the button (It's not really a button...)
<a class="nav-link" href="#" id="disconnettiti">Disconnettiti<span class="sr-only"></span></a>
The problem is: The window.location.replace() succeeds in changing the page and returning back to the login form. But when i click the back button I can also return to the home page, where i called the .replace() function. The replace method should delete the top of the history but this is not the case. Any solutions? Many thanks
There is a basic error in your logic. Restricted area pages should be accessible only with valid grants.
These grants should be deleted when user logs out. So even if you press the back button you don't have the grants anymore and you are redirected to the login page. The same will happen if you try to point to a specific url in the restricted area.
You can use a cookie for example that you set/unset on login/logout or you can use sessions. On each page in the restricted area you need to have the check of the existence of the cookie at the beginning and otherwise the redirect.
Something is working wrong in your application if after logout you can still see things that are inside the restricted area (but you didn't provide code to check that)
EDIT: i saw #scragar comment after i posted my answer but I fully agree with that and not with OP's answer. There are no need for a login page if you don't want to restrict the application. The login becomes completely meaningless if you can access restricted areas anyway
I think you need to give complete url rather than giving a relative path. So if you are serving the page from localhost at port 3000 and index.html is at root, then you should give the path as http://localhost/index.html.
Also, your script must be throwing an error. You should check the browser console first, if something doesn't work.
Hope it helps:)

Jquery - Clear or Remove the URL parameters

Regards, I'm doing a password recovery system in PHP, MySQL and AJAX, the system generates a link with an encrypted code and sends it to the user's mail.
Example of generated encrypted link:
$link = www.dominio.com/reset/?code=98rudrm2093xda
The user has to open the link from your email, to confirm the request, the site detects the code of the URL, using PHP and AJAX desencrita and compares it with the code for the database, if it exists then it creates a new password, this is all done in AJAX, but there is something, if the user returns to reload the web, you are receiving an alert that the code does not exist in the database.
Question:
As I can erase the code of the URL with jQuery, then reset the password, to prevent the alert window appears if I refresh the web page.
Is this possible?
I appreciate your help very much!
What I'm understanding from your question is that you want a method to set up the password reset and not allow re-resetting.
Send email with coded link
Have user click the link and visit the page
Page will get the code GET parameter (PHP or JS)
Do some magic to check if code exists in database (PHP)
If code exists, then allow password reset and delete code from database (PHP)
If not, show error message (PHP)
Redirect to index.html or index.php afterwards (JS)
The last step is to remove the URL variables. If the user checks that same URL again, it will go from step 3 on. Step 4 should stop a re-reset of the password.
You could use this which would technically refresh the page.
window.location.href = window.location.href.split('?')[0];
If you didn't want to refresh or redirect you could use this .pushState() which will update your browser history and change the URL on the page. This would prevent refresh, but hitting the back button on your browser would trigger the refresh again.
EXAMPLE: history.pushState('/some-url');
You could also explore the other HTML5 history API methods like history.replaceState()
However, none of this is probably best practice - I would think your best bet would be to let the querystring remain intact, but only trigger the Alert box / reset on the AJAX return if a password is set correctly.
In other words, have your reset handler return a readable response returning proper headers (eg 200 for success, 4xx for fail, etc), and adjust your $.ajax() call to something more like:
$.ajax({
url: your_url,
data: your_data,
type: 'POST',
success: function(e) {
// Password was reset
// ...show your alert
},
error: function(e) {
// Code wasn't found or reset failed
// ...do nothing or show an error
}
});

Chrome Extension automatically refreshing options page UI

In the options page of my extension, I display the username of the person logged in, along with an option to log out. If they log out, I display instead a link asking them to log in. As well as being able to log in via the options page, they can also do so via the popup.html. The logged-in status is stored in localStorage, which I can access from the options page js.
I would like to be able to listen, in some way, for a change to this status, and update the UI accordingly. If changes are made via the options page, then I of course can change it. However, the issue is if a user logs in whilst via the popup, whilst already on the options page. In that situation, I would still like the options page UI to alter, to now reflect the updated logged-in status. I have thought of 2 different approaches:
(1) Have the background script send a message using chrome.runtime.sendMessage() to the options script every time I change the logged in status.
(2) Add a listener on the localStorage that fires when the logged-in status is changed.
I have tried both approaches, and failed. How can I automatically refresh the UI of my options page depending on the value of a localStorage variable which can be altered from different scripts within the extension?
The answer may be in (1) or (2), however my experience with chrome extensions is limited, so I might have got it programatically wrong and given up too early. Any help would be appreciated.
So I found an answer that allows me to send me message between the background and option page scripts. I had previously tried with chrome.runtime.sendMessage, etc..., however must have made a mistake in the way I implemented it.
options.js script:
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
switch(request.type) {
case "loggedin-status-change":
alert(request.data.myProperty);
break;
}
return true;
});
and the background.js script:
chrome.extension.sendMessage({
type: "loggedin-status-change",
data: {
myProperty: "1"
}
});

Remove POST data when using custom javascript back button

I've coded some custom navigation buttons into the project I'm working on, via javascript - they essentially copy the browser button functionality (brief wasn't initially clear on why separate buttons were required, but they asked for them):
function goBack() { window.history.back(); }
function goForward() { window.history.forward(); }
However, as the functionality is the same as the browser back button, the website asks if I want to resubmit POST data if I go back to a page with said POST data, which is undesirable. Ideally, to fit with the current site setup (all POSTs submit to the originating page, which checks for POST data and performs the relevant submissions to the database), I want to clear the POST data so there is no request to resubmit.
I'm not familiar with the Post/Redirect/Get (PRG) that people might recommend, and it doesn't seem to cover the concept of continually pressing "back"; if you submit a form, you post to a page which handles the post action, then redirects to a GET page - but the redirect is still in the history, meaning if you go back, surely you would hit the redirect page and just be sent "forward"? Plus, PRG seems mostly centred on page refreshing, which is not what I'm looking for at the moment.
The concept of PRG also seems to be due to the browser back button not allowing for additional code to control POST data, so coders have to make the best of what they can access.
With my relative freedom of having a custom back button which could allow for manipulation of POST/session/cookie data, I'd consider there should be some method of calling a global session variable or cookie on back button press, which then gets picked up on the previous page load to unset the POST data and the global session variable/cookie, but my attempts to implement something like this have not succeeded - they've been simple single-line setcookie('back', true) or set($_SESSION['back']=true) PHP snippets within goBack(), with PHP earlier in the page:
<?php if (isset([either set cookie or set session variable]) {
unset([either set cookie or set session variable]); // also tried changing 'true' to 'false' here
unset($_POST);
}?>
Is this kind of behaviour possible and I'm just looking at this from the wrong angle, or is the only way to do a successful back action while suppressing POST to re-engineer the site to use PRG, which will be comparatively significant legwork? Is there some other point in a page load/POST submit that would allow for clearing the POST data, to allow for the back button functionality I'm looking for?
EDIT
I, as an example, navigate to site.com/stuff/edit/[an ID], to edit an item of stuff. The first time I visit, there is no POST data, so the PHP check of isset($_POST) returns false and the page is simply rendered with a form which is populated by a GET.
I amend in the form and press submit. The submit sends the POST data to the target page; this is STILL site.com/stuff/edit/[an ID]! However, because there is now POST data, the PHP picks this up, validates it on the page (you'll see why later) and performs backend model and controller functions to update the item to the database serving the site.
Depending on whether the update was successful, the page then renders the form again, with the information which is retrieved from a GET, which pulls the information from the server (amended or otherwise) and either a success or fail message.
If I want to add a new item, I navigate to site.com/stuff/new; this navigates to the same page as site.com/stuff/edit, but PHP code determines the masking URL and renders different aspects of the code to look like a different page with a different POST action - it also notes there is no ID passed in.
I add an item, and the POST redirects back to the same page; this time, though, there is no Id from the server, meaning the code behind picks up the fact it is a new entry, and performs an insert. It then either displays a success message with a link to view/edit the new item, or a failure message with a prepopulated form to reduce retyping the new item into the form.
I hope this has helped show how this page works; its not necessarily how I would have written the site, but I've inherited the work from an ongoing situation and work with others who code in this way, so I need to be consistent or make unobtrusive changes rather than radical redesigns of in-use code.
I think this should do the job:
function goBack() {
var referrer = document.referrer;
if(referrer != '') {
window.location = referrer;
} else {
window.history.back();
}
}

Check if logged in user liked a page on Facebook API using JS?

Im currently working on a project that require to have fan like a page before he can see several content on the site.
The webpage is not an app in Facebook, it's outside facebook. We will not use PHP or backend code, we will only use FrontEnd
I have finished the user login check to check if user is logged in or not.
I am now stuck with the check if user is a fan of our page. I try to use the function page.IsFan, but somehow it needs to have an UID.
The FQL approach is not possible due to the same reason.
Also another problem is with the appID of our page. I try to google of how to get the appID for page, but the search is mixed up with useless contents.
Is there anyway to either get the UID or check if user liked ourpage without UID?
Thank you very much
You will have to use backend code from your Facebook iFrame fan page because you have to inspect the signed_request variable that is sent in the HTTP POST request to your page, as this variable won't be available via javascript, and subscribing to edge.create in javascript won't work because the page does a full refresh when the user clicks the like button and that event won't fire.
If you are forcing the user to authenticate with your app (which is not nessary if you inspected signed_request variable, you can use a FQL query or graph api request and instead of specifiying their user id, just use "me". something like: select field from table where uid = me()
Unless you provide a UID you won't be able to know whether the user has liked the page previously. However, you can use FB.Event.subscribe to find out when the user does like the item, by subscribing to the edge.create event:
FB.Event.subscribe('edge.create', function(response) {
alert("liked the item");
});
example: http://jsfiddle.net/niklasvh/rmrE4/

Categories