I have one big application, with an admin side and a end-user side. I've had the ability for the admins to impersonate a user within the same broswer/tab for a long time now.
I'd now like to change it up a bit; I'd like the admin to be able to click the impersonate user button and be taken to a new tab and be logged in as that user in the new tab -- but all the while the tab the admin came from must still be logged in as it was.
This is my impersonate user Meteor method:
'click #impersionate-user': (event, instance) => {
event.preventDefault();
if (Session.get('accountId')) {
Meteor.call('impersonate', Session.get('accountId'), (error, id) => {
if (error) throw new Meteor.Error(error);
Session.setPersistent('accountIdBeforeImpersionation', id); // persists accross page refresh
Meteor.connection.setUserId(id);
FlowRouter.go('user.dashboard.view');
});
}
}
});
If I open a new window using something like this:
const win = window.open(FlowRouter.route('/case-details'), '_blank');
win.focus();
How can I control what user to log in as, how can I pass the user to log in as from one tab to the next?
Related
Here is my code:
function googleLogOut() {
debugAlert("googleLogOut:Begin");
GoogleAuth.disconnect();
GoogleAuth.signOut().then(function () {
debugAlert("googleLogOut:Logout Completed, current login status = " + GoogleAuth.isSignedIn.get());
userNotLoggedIn();
debugAlert("googleLogOut:Exit");
});
}
According to my understanding, the disconnect revokes the authorization which the currently signed-in user has granted to my application and the signOut should log the user out of his Google account, basically backing out the OAuth signin which the user went through originally in order to gain access to my application.
However, immediately after GoogleAuth.signOut(), GoogleAuth.isSignedIn.get() evaluates to true - see alert dialog image:
Alert Dialog
Actually, as it turns out, the user is still logged in to his Google account so technically isSignedIn.get() is returning the correct value. I confirmed this by opening a new browser tab and going to gmail - clearly I was still logged in. More to the point though, what this code does is revoke all of the permissions which the user has granted to my application - that is the essence of this logout function. To test this -
GoogleAuth.currentUser.get().hasGrantedScopes(SCOPE) == false
So the compound test for whether a Google account is logged in to my application is:
GoogleAuth.isSignedIn.get() == true && GoogleAuth.currentUser.get().hasGrantedScopes(SCOPE) == true
Here's the modified logout function. (Same functionality, just modified the debug statements to show the revocation of the scopes privileges.)
function googleLogOut() {
debugAlert("googleLogOut:Begin");
GoogleAuth.disconnect();
GoogleAuth.signOut().then(function () {
debugAlert("googleLogOut:Logout Completed, current login status = " + GoogleAuth.isSignedIn.get());
if (GoogleAuth.isSignedIn.get()) {
debugAlert("googleLogOut:Logout Completed, current SCOPE status = " + GoogleAuth.currentUser.get().hasGrantedScopes(SCOPE));
}
userNotLoggedIn();
debugAlert("googleLogOut:Exit");
});
}
Here's a completely different way to do this. I found this to be much more reliable.
logoutWindow = window.open("https://accounts.google.com/SignOutOptions", "_blank", "toolbar=no,width=600,height=400");
I just open a window to Google's account management page. When the user signs out, they are signed out from my application as well.
As the icing on the cake, when I trap the user logged out event in my application I close the window - if the user is logging out through a window which my application has invoked:
try {
logoutWindow.close();
}
catch (err) {
// nothing...
}
Use GoogleAuth.isSignedIn.listen(listener) - when your listener is called the state of GoogleAuth objects has already been updated.
So I recently had acceptance criteria for a site I was building that went as such:
After a user logs in to the site in any tab if they navigate to the site in a new tab they must already be logged in
When a user logs out of any tab they must log out of all tabs immediately
A user can refresh the page and stay logged in
Once all tabs are closed the user is logged out and must log back in
I didn't have access to change the server code (so this had to be done on the client)
I found this Question/Answer which was really helpful
When looking through this I had to rule out cookies because outside of doing a request to the server tab A will no know that tab B had changed the cookie
So I took some parts of the answer from the question above and started using local-storage and added an event to check for if the 'logged-in' state was changed which allowed me to log out in one tab and immediately log out in another without using setInterval to continuously check! Yay
But then I still had the issue of once all tabs were closed if you opened a new tab and navigated to the site you were still logged in.
I tried some possible solutions like having a counter of the tabs that has a session open, decrement and increment on tab close/open (using window.onbeforeunload). ISSUE: refresh of the site when there is only one tab active would log you out. Everything I could think of had an edge case where it didnt work.
local-storage + session-storage!
I would store the value logged-in in both the local-storage and the session storage, when a window was loaded (either a new tab or a refresh of the existing one) it would check local-storage for the 'logged-in' value and if it was not there it would check session-storage!
Basically I am using session-storage to handle the refresh of a page and local-storage to handle multiple tabs. Each time a window/tab is unloaded (closed or refreshed) I delete the local-storage 'logged-in' and when I come back into the page if it is in session-storage but not in local-storage I put it back into local-storage from the session-storage and continue as an authenticated user
Here is the code for this:
On login:
localStorage.setItem('logged-in', true);
sessionStorage.setItem('logged-in', true);
In my base component:
window.onbeforeunload = (event) => {
localStorage.removeItem('logged-in');
}
let loggedIn = localStorage.getItem('logged-in');
let sessionLoggedIn = sessionStorage.getItem('logged-in');
if(!loggedIn) {
if(sessionLoggedIn) {
localStorage.setItem('logged-in', JSON.parse(sessionLoggedIn));
//go to authenticated space
window.location.href = '/authenticated';
} else {
//go to login
window.location.href = '/login';
}
} else {
//go to authenticated space
window.location.href = '/authenticated';
}
window.addEventListener('storage', (event) => {
if (event.key == 'logout' && event.newValue) {
sessionStorage.removeItem('logged-in');
localStorage.removeItem('logout');
window.location.href = '/login';
}
});
On logout
localStorage.setItem('logout', true)
Hope this helps some of you if you ever find yourself in a similar situation
Im using webRTC plugin named (RTCMultiConnection) but if user has his cam on and leave somehow his session stays alive. Because if user1 opens cam, than leaves, again comes back and opens cam than it's not able to join it's cam.
Im trying to append the new connections like;
Webcam.connection.onNewSession = function(session) {
console.log("On new session")
createSession: function(session){
Webcam.sessions[session.sessionid] = session;
$("div").append($("<div />", {
class: "webcam-live ct icon-isight",
html: "LIVE"
}));
}
};
First time opening the cam it appends whenever same user leaves and comesback it doesnt trigger for others. But if take another username than it sends its to new users
Source
Im implementing auth using this and am currently showing a loading icon in React when a user clicks the button to sign in and the auth2 account selection/login window shows.
However if a user closes the window, there doesnt seem to be any event fired i.e the signIn() function which returns a promise never resolves, I would have thought google would return an error for this promise if the window is closed. As a result there is no way for me to stop showing the loader icon and reshow the login menu.
I was wondering if anyone had a solution for this?
I try to modifiy my code that call Google OAuth 2.0 window.
You only have to add extra AJAX method that cover what is Google OAuth error result.
gapi.auth2.getAuthInstance().signIn()
Change it to this one,
gapi.auth2.getAuthInstance().signIn().then(function(response){
//If Google OAuth 2 works fine
console.log(response);
}, function(error){
//If Google OAuth 2 occured error
console.log(error);
if(error.error === 'popup_closed_by_user'){
alert('Oh Dude, Why you close authentication user window...!');
}
});
That's it...
For more detail about Google OAuth 2.0 information, you can visit this link.
https://developers.google.com/api-client-library/javascript/samples/samples#authorizing-and-making-authorized-requests
Sample code on JavaScript:
https://github.com/google/google-api-javascript-client/blob/master/samples/authSample.html
Although the API provides a mechanism for detecting when the user clicks the Deny button, there is not a built-in way for detecting that the user abruptly closed the popup window (or exited their web browser, shut down their computer, and so on). The Deny condition is provided in case you want to re-prompt the user with reduced scopes (e.g. you requested "email" but only need profile and will let the user proceed without giving you their email).
If the response from the sign-in callback contains the error, access_denied, it indicates the user clicked the deny button:
function onSignInCallback(authResult) {
if (authResult['error'] && authResult['error'] == 'access_denied') {
// User explicitly denied this application's requested scopes
}
}
You should be able to implement sign-in without detecting whether the window was closed; this is demonstrated in virtually all of the Google+ sample apps. In short, you should avoid using a spinner as you're doing and instead should hide authenticated UI until the user has successfully signed in.
It's not recommended you do this, but to implement detection of the pop-up closing, you could do something like override the global window.open call, then detect in window.unload or poll whether the window was closed without the user authenticating:
var lastOpenedWindow = undefined;
window.open = function (open) {
return function (url, name, features) {
// set name if missing here
name = name || "default_window_name";
lastOpenedWindow = open.call(window, url, name, features);
return lastOpenedWindow;
};
}(window.open);
var intervalHandle = undefined;
function detectClose() {
intervalHandle = setInterval(function(){
if (lastOpenedWindow && lastOpenedWindow.closed) {
// TODO: check user was !authenticated
console.log("Why did the window close without auth?");
window.clearInterval(intervalHandle);
}
}, 500);
}
Note that as I've implemented it, this mechanism is unreliable and subject to race conditions.
The webkitNotifications API in Chrome won't let me redirect to a page when the user clicks on the notification.
Is there any way I can make it work like Growl on the Mac, with a notification popping up, and then the user clicking on it to be redirected? For example, the user receives a new message, is notified via webkitNotifications, clicks on the message and is taken to message.php.
Maybe you should try this (onclick)
function setNotifJL(strtitre,strmsg) {
if (window.webkitNotifications.checkPermission() == 0 ) {
Window.webkitNotifications.createNotification('../mypic.gif',strtitre, strmsg);
n.show();
n.onclose = notify;
n.onclick = nclicked;
}
}
function notify() {location.href='<whereever you want';}