Emberjs route is unable to access authenticated user - ember.js

My Ember app will show user's information after they are authenticated. I am doing authentication with Firebase and the user the is being authenticated, but the route seems to trying to find the user before this happens. It gives me this error:
Assertion Failed: You cannot pass `undefined` as id to the store's find method
Any idea how to fix this/ why it is happening?
Here is my application route with the login function:
login: function(email, password) {
this.get('session').open('firebase', {
provider: 'password',
email: email,
password: password
}).then(function() {
this.transitionTo('index');
}.bind(this));
},
logout: function() {
this.get('session').close().then(function() {
this.transitionTo('application');
}.bind(this));
}
Here is my index route:
model: function(params){
return this.store.find('user', params.user_id);
}

Related

A token request using ember-simple-auth-token won't include the identification field

A have an Ember (v2.12.0-beta.1) app that uses ember-simple-auth-token to request a JWT.
The important part happens in the login controller.
export default Ember.Controller.extend({
session: Ember.inject.service(),
// Properties
username: 'user1',
password: 'password123',
// Actions
actions: {
login(username, password) {
console.log('Attempting login...');
let creds = this.getProperties('username', 'password');
let authenticator = 'authenticator:jwt';
this.get('session').authenticate(authenticator, creds).then(function() {
console.log('LOGIN SUCCESS')
}, function() {
console.log('LOGIN FAIL')
});
}
}
});
When submitting the form, there is a request that is being made by the browser and my backend receives it.
The problem is that only the password is included in the request. The body of the request has the form {"password":"password123"}, but it should look like {"username":"user1","password":"password123"}. Of course, the login attempt fails and LOGIN FAIL is printed.
Why is the username not included in the token request?
I tried using earlier versions of ember-simple-auth-token and ember-simple-auth.
Here is my configuration:
ENV['ember-simple-auth'] = {
authorizer: 'authorizer:token',
};
ENV['ember-simple-auth-token'] = {
serverTokenEndpoint: 'http://127.0.0.1:6003/token',
identificationField: 'username',
passwordField: 'password',
tokenPropertyName: 'token',
authorizationPrefix: 'Bearer ',
authorizationHeaderName: 'Authorization',
refreshAccessTokens: false,
};
ember-simple-auth-token expects credentials object passed to authenticate to be in format:
{
identification: <username>,
password: <password>
}
So your code should look something like this:
actions: {
login(username, password) {
console.log('Attempting login...');
let creds = {
identification: username,
password: password
};
let authenticator = 'authenticator:jwt';
this.get('session').authenticate(authenticator, creds).then(function() {
console.log('LOGIN SUCCESS')
}, function() {
console.log('LOGIN FAIL')
});
}
}
The request sent in this case is:
{
"password":"password123",
"username":"user1"
}
There are some pull requests about this issue.

Ember store data to django backend

I'm new to Ember and I'm trying to communicate with a django server via RESTful API. So far I have managed to get the information from the server but if I try to send some information back I get a "CSRF Failed: CSRF token missing or incorrect." error.
In the resources of Chrome's developer tools I can see that I don't have any cookie. I've read that I should the "X-CSRFToken": "cookie" in my adapter but since I don't have a cookie I don't know what to do.
So I' m in dead end...
Here is my code:
Server Response:
[{"username":"user1","password":"123","email":"user1#example.com"},
{"username":"user2","password":"456","email":"user2#example.com"}]
Ember Model:
import DS from 'ember-data';
export default DS.Model.extend({
username: DS.attr(),
password: DS.attr(),
email: DS.attr()
});
Ember Adapter:
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
host: '/api',
contentType: 'application/json',
dataType: 'json',
headers: {
username: 'XXXX',
password: 'XXXX'
},
buildURL: function(modelName, id, snapshot, requestType, query) {
var url = this._super(modelName, id, snapshot, requestType, query);
return url + "/";
}
});
Ember Serializer:
import DS from 'ember-data';
export default DS.JSONSerializer.extend({
primaryKey: 'username'
});
Ember Route: import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.findAll('account');
}
});
Ember Controller:
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
signup(){
console.log('My username is: ', this.get('username'));
console.log('My password is: ', this.get('password'));
console.log('My email is: ', this.get('email'));
var account = this.store.createRecord('account', {
username: this.get('username'),
password: this.get('password'),
email: this.get('email')
});
account.save();
}
}
});
Thank you in advance for your help.
I resolved my issue.
The problem was that I was using http://localhost:4200/ instead of http://127.0.0.1:4200/ and that's why I couldn't find django's cookie.
As soon as I found django's cookie, I just add an attribute to the header of the adapter.
My new adapter is shown below:
Ember Adapter:
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
host: '/api',
contentType: 'application/json',
dataType: 'json',
headers: {
"X-CSRF-Token": 'django token',
username: 'XXXX',
password: 'XXXX'
},
buildURL: function(modelName, id, snapshot, requestType, query) {
var url = this._super(modelName, id, snapshot, requestType, query);
return url + "/";
}
});

Whitelist requests from certain routes

Whenever a user is not authenticated they are transitioned to the login route/view. I am needing a way for a user to be able to get to a few routes when they aren't authenticated like 'password-reset', 'new-password', etc. Is there a way to whitelist the requested route and if it's not one of those routes transition to the login route? Thanks in advance for the help.
App.ApplicationRoute = Ember.Route.extend
model: ->
store = #controllerFor('application').get('store')
if !$.cookie('apiKey')
#transitionTo 'login'
return store.createRecord('session')
store.find('session', 'current').then (session)->
session
, (error)=>
if error.status == 403
#transitionTo 'login'
return store.createRecord('session')
else
throw error
App.Router.map(function() {
this.resource('auth', function(){
this.resource('colors', {path:'/colors'}, function(){
this.resource('color', {path: '/:id'});
});
});
this.resource('unauth', function(){
this.resource('dogs', {path:'/dogs'}, function(){
this.resource('cats', {path: '/:id'});
});
});
});
App.AuthRoute = Em.Route.extend({
model: function(){
store = #controllerFor('application').get('store')
if !$.cookie('apiKey')
#transitionTo 'login'
return store.createRecord('session')
store.find('session', 'current').then (session)->
session
, (error)=>
if error.status == 403
#transitionTo 'login'
return store.createRecord('session')
else
throw error
}
});

Resource path parameter not passed to Route

Somehow the parameter user_id is not being passed to my UserIndexRoute. What could be going wrong?
The error I'm getting as a result is
Assertion Failed: You may not pass undefined as id to the store's
find method
The request is /users/1
A user with id 1 does exist in its model fixtures
There are no other errors in my app, the users route is working and showing the fixturedata for user
router.js
var Router = Ember.Router.extend({
location: DaappEmber2ENV.locationType
});
Router.map(function() {
this.resource('users', function(){
this.resource('user', { path:'/:user_id' }, function(){
this.route('edit');
});
this.route('create');
});
});
export default Router;
routes/user/index.js
export default Ember.Route.extend({
model: function(params){
Ember.Logger.debug('Params for user/index route:', params);
return this.store.find('user', params.user_id);
}
});
You've defined a dynamic slug, user_id on the users route, but then you are trying to access it on the usersindex route. Child route's don't inherit params from their parent resources. Create a users route and it will be available there.

Ember output vars form other controllers / models in a view

I think i have a fundamental problem of understanding how to access vars in a View form other controllers.
I read the Ember-Documentation many times and "hundreds" of Blog-Entries, but i did not find a solution.
After Submitting a Loginform, i want to set the var "isLoggedIn" from Auth Controller / Model and output it in the Login View. Auth will be used later from many other Components, thats why i want to separete it from Login.
Here is a small part of my code:
Template: Login
Authenticated: {{controllers.auth.isLoggedIn}} <--- after Login this should be TRUE, but how ?
...LoginForm: here is the login form with input fields (email and password)...
Controller: Login
var LoginController = Ember.Controller.extend({
needs: "auth",
// LoginForm Submit-Event
login: function() {
App.Login.createRecord(this.getProperties("email", "password"));
DS.defaultStore.commit(); // on server respond, id of model.login is changed, see "idObserver"
}
});
Model: Login
var Login = DS.Model.extend({
email : DS.attr("string"),
password : DS.attr("string"),
// Because of Ember Bug i have to use idObserver after "DS.defaultStore.commit()"
// to get the ID responded from the server.
idObserver: function() {
var auth = App.Auth.create();
auth.set("id", this.get("id"));
}.observes("id")
});
Controller: Auth
var AuthController = Ember.Controller.extend({
isLoggedIn: false // What should i write here to connect to isLoggedIn of Auth.Model ???
}); // Controller
Model: Auth
var Auth = Ember.Object.extend({
isLoggedIn: DS.attr("boolean"),
idObserver: function() {
if(this.get("id")) this.set("isLoggedIn", true);
else this.set("isLoggedIn", false);
}.observes("id")
});
How can i output "controllers.auth.isLoggedIn" in the Login Template ?
Normally the instance of the auth model would be set on the content property of your auth controller (typically handled by the router). Once the content is set then your template would work with no modifications.
This gist might help you out as it as a login example using the router:
https://gist.github.com/machty/5647589