meteorjs persistent setUserId to switch user - javascript

i'm trying to use meteor this.setUserId() server side and Meteor.connection.setUserId() client side . It is to let admin have control on all users accounts and to be able to login without passwords.
Server side:
Meteor.methods( {
"switchUser": function(user_id) {
this.setUserId(user_id);
return user_id;
}
});
client side:
Meteor.call("switchUser", user_id , function(error, idUser) {
Meteor.connection.setUserId(idUser);
Router.go('/profile');
});
It's working but is not persistent. After refresh or moving to another page ,the logged-in user is restored to the first (admin).
How can i swith user permanently with meteorjs ?

I dont know if it works but if you look on local storage you see that its set a login token Meteor.loginToken also among with user id Meteor.userId, maybe you have to set that too for the new user when you switch. Or you should consider making a method for login without password https://github.com/meteor/meteor/blob/master/packages/accounts-base/accounts_server.js#L107

Related

Firebase initialize app lose Current User

I have a web application using html-js-css and a flask server.
My web app is a multi-pages app which apparently means that I have to Initialize firebase for each page in which i want to use it -.-
The problem is that every time I initialize firebase app, I lose the current user so while in my main page, after log-in, if I write:
const USER = firebase.auth().currentUser;
console.log(USER.uid);
I get my user ID, as soon as I move to another page and repeat the above code, I get the error:
TypeError: USER is null
Is there a way to either:
avoid Initializing the firebase-app at avery page
keep the CurrentUser (even storing it securely somewhere)
Thank you
Workaround:
I got this workaround working before Frank answer which is probably the best way to proceed. Instead I just stored the user id in an encrypted variable accessible to all pages.
Since the main.html page is always loaded, I store/removed the variable in a onAuthStateChanged listener there so as soon as the user is logged out, that variable is removed:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
cached_uid = JSON.stringify(user.uid);
cached_uid = btoa(cached_uid);
localStorage.setItem('_uid',cached_uid);
} else {
localStorage.removeItem('_uid');
}
});
then on the other pages:
function loadUID(){
var uid = localStorage.getItem('_uid');
if (!uid) return false;
uid = atob(uid);
uid = JSON.parse(uid);
return uid
}
I followed this to find this solution:
How to send variables from one file to another in Javascript?
You will need to initialize the Firebase app on each page, but that is supposed to be a fairly cheap operation.
To pick up the user on the new page, Firebase runs a check against the server to ensure the user token is still valid. Since this code calls a server, its result likely isn't available yet when your firebase.auth().currentUser runs.
To solve this, run the code that requires a user in a so-called auth state change listener:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
Also see the Firebase documentation on getting the currently signed in user.

Keep user logged in in app even after the app closed using Async Storage

I am trying to maintain a user as logged in, in an app even after the app closed, which means the user will no longer need to re-enter his/her userID and password again everytime he/she opens the app.
I want to achieve this using AsyncStorage (other than redux), my question is: is it possible to do so using AsyncStorage? I found sources online on how to persist data using Async but U could not connect those with what I wanted to do.
You should do it this way:
User opens the app, may be do this in you splash screen's didMount i prefer these kind of things to be done before hand in the splashsreen only. Check a flag in AsyncStorage say isLoggedIn if thats true, fetch
user credentials from the AsyncStorage and fed them to your login
request and the rest of the app flow continues.
If isLoggedIn is false (or null), show login screen to the user and upon successful login, save the credentials to AsyncStorage and on success must save the isLoggedIn flag to true and rest of the app flow continues.
For point 1, the code should look like:
AsyncStorage.getItem('isLoggedIn').then((value) => {
if(value && value === 'YES') {
//hit login api using the saved credentials and take user inside the application.
} else {
//Take user to login page and progress with point 2.
}
});
and below is the code that should work for point 2 upon success of login.
const encrypted_username = myFancyEncrptionFunction(username);
const encrypted_password = myFancyEncrptionFunction(username);
AsyncStorage.setItem('username', encrypted_username).then(()=>{
AsyncStorage.setItem('password', encrypted_username).then(()=>{
AsyncStorage.setItem('isLoggedIn', 'YES');
});
});
Its totally upto you how you want your user's credentials to be saved in AsyncStorage i.e. with or without encryption. But its always recommended to keep such things encrypted.

In Meteor, how/where do I write code that triggers when an authorized user has logged in?

New to Meteor, I'm using the alanning:roles package to handle roles.
I've managed to be able to only publish a collection when a user is logged in, when the page is first refreshed.
Meteor.publish('col', function(){
if (Roles.userIsInRole(this.userId, 'admin')) {
console.log('authed');
return Sessions.find({});
} else {
console.log('not auth');
// user unauthorized
this.stop();
return;
}
});
Logging out kills access to the collection (I'm using mongol to see). Logging back in after logging out, or logging in from a logged out state when the page is first loaded, will not give me access.
The webapp I'm trying to build is something like an ticketing system. I'm trying to be secure, so no unnecessary publishing if the user is not authorized.
What I'm trying to do is, get ticket information submitted from users from a collection, and display it on the client screen (as long as the client is authorized first). Maybe a better way to handle this is to force a refresh (how do I do that?) after a user change so unauthorized users are "kicked" out? And render all relevant data from the private collection right after the user is authorized?
I actually managed to get what I want for now with helpers...
In my ./client/Subs.js file:
Meteor.subscribe('col');
Template.NewTicket.helpers({ // match the template name
// move this into method later, not secure because on client??
isAdmin() {
console.log('is admin.');
console.log(Meteor.userId());
Meteor.subscribe('col');
return Roles.userIsInRole(Meteor.userId(), 'admin');
},
});
and then somewhere in my template file ./client/partials/NewTicket.html:
<template name="NewTicket">
{{#if isAdmin}}
{{/if}}
</template>
to trigger the check? I'm 99% sure theres a better way.

Single Sign out in All application using Auth0

I have URL "http://mywebsite.com" like this. I am using Auth0 for login my web application.Once the user logged in my application i will logging the user to my wordpress site and other website using the same login(Single Single Sign On). Once the user logged out from my application I need to logged out from wordpress and other website Also(Single Sign OFF/OUT).
Is it possible?
please suggest better option
Haven't had any experience with doing this personally, but this is straight from the docs on Auth0:
"This will clear any single sign-on cookies set by Auth0 for that user. If you also want to log the user out of their identity provider, add a federated query string parameter to the logout URL:
https://appname.auth0.com/v2/logout?federated"
I have the same requirement at this point. I am also using Auth0.
From their documentation, I understand that calling the Auth0 logout endpoint will only clear the SSO cookie on Auth0 and It does not logout of all other applications. It is our responsibility to clear the Sessions for each application.
The same is explained using a Auth0 anjularjs sample here https://github.com/auth0/auth0-single-sign-out-sample
Hope this helps.
#udayr answer led me on the right path:
I'm actually using ASP.Net Owin, so I created an overload of the LogOff endpoint at the Auth0AccountController of all my Apps like this:
[HttpGet]
public ActionResult LogOff() {
return this.LogOff("");
}
Then I added an SLO (Single Log Of) view and put the following code on it:
<iframe id="app1" height="0" width="0" src="http://app1.localtest.me/Auth0Account/LogOff"></iframe>
<iframe id="app2" height="0" width="0" src="http://app2.localtest.me/Auth0Account/LogOff"></iframe>
<h2 id="message">Logging off, please wait...</h2>
<script>
var app1Ready = false;
var app2Ready = false;
$('iframe').load(function (e) {
switch ($(e.target).attr("id")) {
case "app1":
app1Ready = true;
break;
case "app2":
app2Ready = true;
break;
}
if (app1Ready && app2Ready) {
$("#message").html("You have been Logged Off successfully!");
}
});
</script>
Basically, we need to make a Get call to the new LogOff end point via the iframes, the oly drawback is that all the aplications needs to know all the others applications' Log Off URLs, and this needs to implemented on all of them.
To log out the user from multiple applications, you can always check auth0 session has expired or not for the user by using the checkSession() method periodically. If there is no active session for the user, you can log out the user from your application.
// check every 15 minutes if the SSO session is still active
setInterval(function() {
// if the token is not in local storage, there is nothing to check (that is, the user is already logged out)
if (!localStorage.getItem('userToken')) return;
auth0.checkSession(function (err, data) {
if (err) {
// if we get here, it means there is no session on Auth0,
// then remove the token and redirect to #login
localStorage.removeItem('userToken');
window.location.href = '#login';
}
});
}, 900000)
https://auth0.com/docs/sso/current/single-page-apps#single-log-out
https://auth0.com/docs/migrations/guides/legacy-lock-api-deprecation#session-management
To clear the server session, all you need to do to redirect the user to /v2/logout endpoint.
https://auth0.com/docs/logout/guides/logout-auth0
If the users are logging in using the external identity provider, you can force the user to logout from IDP by adding federated querystring parameter when calling /v2/logout endpoint
https://auth0.com/docs/logout/guides/logout-idps
In the case of SAML IDP, you must configure SAML Logout URI in the connection settings.
https://auth0.com/docs/logout/guides/logout-saml-idps

Express and realtime apps. Persist updates from client to server to client

I am writing a realtime app. The basic principle is like a chat, but instead of text messages, users share youtube videos. The backend hasn't been completely done yet, and I don't know how I will do it. But I have some questions for what has been done.
Right now, user authentication with user/pass, FB, Twitter works well, and credentials are being stored in my db. User sign in works fine as well. Error messages get flashed fine.
I'm using mongodb (mongoose) and express on the backend. It is not an API based design because I don't know how to work with user authentication in API's (I can make GET/POST/PUT/DELETE API, just don't know how to fit in authentication in there).
When a user, say, signin's using the homepage, the credentials are verified using req.body.<field> in an express.js route. If authenticated, redirect the user to a dashboard, else redirect to signin with flash messages. So, there are no Ajax calls, and right now, the app isn't realtime in any way. I'd like it to be realtime though.
So, leading to that, I have 3 questions:
I am using a modal window (bootstrap), to ask the user to update profile. The modal shows fine, except the field I want to be shown are not shown. The password and email fields are empty, even though I have a value attribute.
input.form-control.dash(type="password", name="newuserpassword", ng-minlength=8, ng-model="password", value="__USE_EXISTING__")
input.form-control.dash(type="email", name="newuseremail", required=true, ng-model="email", value=user.email)
http://snappy-app.com/s/read.php?pass=9fc7ffa1e2b2140aad5232d5733f4caf
I want that when user edits the "Save" button, a message in the modal should either how any errors, or show that the update was successful. As it is, right now, my update method doesn't do this. Beyond redirecting the user, I don't know how can I achieve what I want.
exports.update_user = function(req, res) {
var user = new User({
'username' : req.user.username,
'password': req.body.newuserpassword || ,
'email': req.body.newuseremail
});
console.log(user);
user.save(function(err) {
if (err) {
console.log(err);
for (var field in err.errors) {
var error = err.errors[field].message;
req.flash('error', error);
}
res.redirect('/dashboard');
} else {
req.logIn(user, function (err) {
if (!err) {
req.flash('success', 'Done!');
} else {
req.flash('error', 'Something went wrong.');
}
});
}
});
}
After the user updates the values by clicking "Save", the modal will close. The user can still click on the "Edit" link to change values yet again, and the modal will open. Now, based on what I have read, the user won't see the changes, because there hasn't been a page/modal reload. How do I make sure that the user sees updated values?
Any help is appreciated.
When I read your text, I think:
"Hum, he tried to make an Ajax call and let the view display the errors or go on"
When I read your code, I think:
"Hum, it's a synchrone "give me all the page" call"
Which version do you want?
The Async one? So we can explain you the Ajax principle and your real problem is an UI update.
The Sync one? It's definitively an UI problem, and you should add a tag for it.

Categories