Currently I have a store that I am loading in my app.js at runtime:
stores: ['Neighbors']
Its autoLoad property is set to true.
I've now added a login system that is loaded if some info isn't found in localStorage:
//show login if user credentials are unknown
var username = window.localStorage.getItem("email");
var user_id = window.localStorage.getItem("user_id");
if(username == '' || username == undefined || user_id == '' || user_id == undefined) {
Ext.Viewport.add(Ext.create('aa.view.Login'));
} else {
Ext.Viewport.add(Ext.create('aa.view.Main'));
}
The login view fires an ajax request to log the user in, and the user's id and some other info is returned on success:
onLoginButtonTap: function() {
var values = this.getLoginForm().getValues();
var that = this;
// do the ajax login
Ext.Ajax.request({
url: 'http://localhost:8000/session',
method: 'POST',
params: values,
timeout: 10000, // time out for your request
success: function(result) {
// let's get the email and id into local storage
var json = Ext.decode(result.responseText);
console.log(json);
window.localStorage.setItem('user_id', json.user_id);
window.localStorage.setItem('email', json.email);
// var neighborsStore = Ext.getStore('Neighbors');
// neighborsStore.load();
// load up the tab holder and destroy the login view
Ext.getCmp('loginForm').destroy();
Ext.Viewport.add(Ext.create('aa.view.Main'));
},
failure: function(){
Ext.Msg.alert("Login Failed");
}
});
}
I use the user_id in my store to get a list of other users nearby. The only problem is, my user_id isn't known unless my user has logged in.
I either need to refresh the store, or I need to defer its loading until after a successful login. I'd rather do the second option and only attempt to load the store after login.
I can't seem to find any info on how to do this. I've tried
Ext.getStore('storename').load()
but it isn't refreshing the store. I've tried setting autoLoad to false but then the store never loads. How do I defer loading?
You should be able to use that.getNeighborsStore().load() in your success function. This will load the store once the user has successfully logged in.
Related
I can't seem to understand the relation between Accounts.createUser() and Accounts.onCreateUser(). I have an external api that validates the users' login credentials. Once the api sends me a positive response, I need to add the user in MongoDB and start its session so it can be considered as a logged in user. Accounts.createUser() is creating a user on server side, but I need Accounts.onCreateUser() because I need to add custom fields like user's token that is being generated from the external api.
This is the code I have right now (which doesn't add a user at all):
server-side code:
var request = {
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
},
'params': user
};
try {
var response = HTTP.call('POST', url, request); //send call to the external api
var token = response.data.token;
//decode the token and add the user in the database
var userInfo = Base64.decode(token.split('.')[1]);
var options = {
email: user._username,
profile: {
name: user._username
},
token: token
};
var user = Accounts.onCreateUser(function(options, user) {
if (options.token)
user.token = options.token;
if (options.profile)
user.profile = options.profile;
return user;
});
console.log(user); //this returns undefined
return JSON.stringify({
'code': 200,
'token': userInfo
});
} catch (error) {
console.log(error);
//console.log(error.response);
var body = error.response.content;
return body;
}
Okay. So I finally found what I had been looking for. The relation between Accounts.createUser and Accounts.onCreateUser is that Accounts.onCreateUser is a hook and adds extended functionality to the original Accounts.createUser function. What is the extended functionality? It lets you create additional fields prior to actually inserting your user in the database. You have to write this hook in your main.js (server side) in the startup code snippet:
Meteor.startup(() => {
Accounts.onCreateUser(function(options, user) {
if (options.token)
user.token = options.token;
if (options.profile)
user.profile = options.profile;
return user;
});
})
And wherever you want to add the user, simply call Accounts.createUser() and this hook will be called automatically prior to the createUser call
I realized the authorization of the user through the passport (Koa, Mongodb, React, Redux).
router.post('/login', function(ctx, next) {
return passport.authenticate('local', async function(err, user, info) {
if (err) throw err;
if (user === false) {
ctx.status = 401;
ctx.body = { error: info };
} else {
ctx.body = {
success: true
};
await ctx.login(user);
}
})(ctx, next);
})
If the user logged in, he redirects to the profile page(main page).
router.get('/login', function(ctx, next) {
if (ctx.isAuthenticated()) {
ctx.redirect('/');
} else {
ctx.body = fs.readFileSync(path.resolve(path.join('build', 'index.html')), 'utf8')
}
});
Since I have a spa I always pass a static file (routing on the client via a react-router)
The problem is that I can not understand how I get information about the user when the profile page is loaded
If I send a ajax-request (feth) from the React-component, then the request for another session id and it is not associated with the user.
Or, I need to do this on the server, but how I might to use the store storage on the server?
How best to solve this problem?
Well, while it might not be the best way, the easiest way to do this would be to have a section in your html file like..
<script type="text/javascript">
window.currentUser = $$USER$$
</script>
And then do a replace on the body.
let content = fs.readFileSync(path.resolve(path.join('build', 'index.html')), 'utf8')
content = content.replace('$$USER$$', JSON.stringify(user))
ctx.body = content
In your React app, you can use window.currentUser.
I want to add a push token to an user in my application. I have the push token, I have the user, but I can't add the token to the user. How I can add the push token to this user?
Here is the code:
var io = Ionic.io();
username = localStorage.getItem('username');
var signupSuccess = function(user) {
// The user was authenticated; you can get the authenticated user
console.log(user);
};
var signupFailure = function(errors) {
for (var err in errors) {
// Check the error and provide an appropriate message
// for your application.
user = Ionic.User.current();
}
};
var details = {
'email': 'email#gmail.com',
'password': 'pass2',
'username': 'username'
}
Ionic.Auth.signup(details).then(signupSuccess, signupFailure);
var push = new Ionic.Push();
var user = Ionic.User.current();
var callback = function(pushToken) {
alert('TOKEN: ' + pushToken.token);
user.addPushToken(pushToken);
user.save(); // You NEED to call a save after you add the token
}
push.register(callback);
It's no longer user.addPushToken(pushToken);
Instead you need:
push.register(function(token) {
push.saveToken(token);
});
This will automatically add the token to the currently logged in Ionic user.
See this example from Ionic documentation
N.B. as you're adding this at the point that the user is signing in, you also need to add the above code to register for push inside your $ionicPlatform.ready function:
$ionicPlatform.ready(function() {
var push = new Ionic.Push();
push.register(function(token) {
push.saveToken(token);
});
});
Or more likely, create one function to register for push which is called both from within $ionicPlatform.ready and also from within your signup / signin functions.
Otherwise, if Push has not been registered inside $ionicPlatform.ready, it won't add the token to your user when you call push.saveToken after signup / signin.
I can suggest one thing. You can ask the backend or server to team add a user token in the database or else.
You can manually add the following thing if it is an JSON object:
user["token"]=value
In my routing file I have the following down.
Router.route('/user/:createdBy', {
name: 'user',
/*onBeforeAction: function () {
AccountsEntry.signInRequired(this);
},*/
fastRender: true,
data: function () {
paramId = this.params.createdBy;
// Still have to find a way how to get data
// Function below is only for signed in users
return Meteor.users.findOne(paramId);
}
});
In my user template I want to display the email. I have it like this {{emails.[0].address}} and as {{users.emails.[0].address}} but the email doesn't show up. It only shows up if the user is logged in. I however have the users Id as my param. (This is for testing purposes guys!).
If you want to use the logged off user information, you could try this:
// in your router.js
// callback would be called when login is successful
Meteor.onLogin(function(){
Session.set('login user', Meteor.user());
})
// in your template, or other functions
// the Session would be update only if a user login successfully
var userId = Session.get('login user')._id;
Click here for more details.
I wish it could help :-)
I use REST API in JavaScript. When I request REST API multiple times, it returns(response) invalid session id, but I am providing a valid session id, because I have pulled data with this session id.
Anyone came across this issue?
function sugarLogin(url, user, password) {
var request = new XMLHttpRequest();
var params = {
user_auth: {
user_name: user,
password: password
},
name_value_list: [{
name: 'notifyonsave',
value: 'true'
}]
};
var json = $.toJSON(params);
var crm_api = url;
request.open("POST", crm_api, true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
var response = request.responseText;
var response_obj = jQuery.parseJSON(response);
if (response_obj) {
if (response_obj.name && response_obj.name == "Invalid Login") {
//invalid login
ProcessingFlag = 3;
} else {
session_id = response_obj.id;
ProcessingFlag = 1;
}
}
} else if (request.readyState == 4 && request.status == 404) {
ProcessingFlag = 2;
}
}
request.send("method=login&input_type=JSON&response_type=JSON&rest_data=" + json);}
I have used above code to login and set session_id (global scope)
and then using this session id I am calling search_by_module function of REST API.
It is working fine but if made multiple requests frequently then it says invalid session id.
Although I have tried to call login function again before making search_by_module call.
Main issue is when I tried calling other REST function after response returned from search_by_module and rendered HTML, it says me invalid session. I can't figure out why session expires immediately while we know that on server session expires after 24 minutes (server where our sugar instance hosted)
I bet you're getting this because of item number 3 :
1/ Defined an error callback that checks for that particular response -invalid login- and calls the login function. Reading your code, I guess this is ProcessingFlag = 3; job.
2/ make sure the login function updates the session_id correctly and globally so that future function calls will get the correct value.
3/ make sure you're passing that new session_id to all your subsequent calls as FIRST parameter in all you rest_data. I got caught on this and lost many hours only to find out that SugarCRM DOESN'T support named parameters in its rest_data (is it poorely implemented function-arguments-wise ?) This is because I was adding session_id as last parameter and all of my REST calls were returning invalid ID.