Error Nothing handled the action 'sessionInvalidationSucceeded' using Simple Auth Ember JS - javascript

So I have been setting up a auth manager through my ember for the past week a and finally got it working. However, I'm still getting a error when invalidating the user.
Nothing handled the action 'sessionInvalidationSucceeded'
Can't figure out what the best way to handle the error?
import Ember from 'ember';
import DS from 'ember-data';
export default Ember.Object.extend({
authenticate: function(controller, user) {
var app = this.container.lookup('controller:application');
var session = app.get('session').authenticate('simple-auth-authenticator:oauth2-password-grant', user);
session.then(function() {
console.log('Session Started');
controller.transitionToRoute('brands');
});
},
endSession: function() {
var app = this.container.lookup('controller:application');
var session = app.get('session').invalidate();
session.then(function() {
app.store = DS.Store.create();
console.log('Session Ended');
app.transitionToRoute('index');
app.store.destroy();
});
}
});
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
sessionEnded: function() {
this.authManagerService.endSession();
}
},
currentUser: function() {
return this.store.find('user', this.session.get('user_id');
}.property('#each.user')
});

You need to include the Simple Auth Route mixin on the route you are authenticating
import ApplicationRouteMixin from 'simple-auth/mixins/application-route-mixin';
or handle the action in your initializer
Ember.Application.initializer({
name: 'authentication',
after: 'simple-auth',
initialize: function(container, application) {
var applicationRoute = container.lookup('route:application');
var session = container.lookup('simple-auth-session:main');
// handle the session events
session.on('sessionInvalidationSucceeded', function() {
applicationRoute.transitionTo('index');
});
}
});
Take a look at the api, it's really helpful
http://ember-simple-auth.com/ember-simple-auth-api-docs.html#SimpleAuth-ApplicationRouteMixin-sessionInvalidationSucceeded

Related

Javascript ServiceStack Client serialization error

So I have a master/detail scenario between two views. The master page shows a list and after clicking on one of the items, I send a message via the EventAggregator in Aurelia to the child view with a deserialized dto (coming from the selected item of the master) as a payload of the message.
However when I then try to pass this item as a parameter of a subsequent request in the child (to get additional info) the payload object fails to serialize.
Master.ts:
import { JsonServiceClient } from "servicestack-client";
import {
ListPendingHoldingsFiles,
ListPendingHoldingsFilesResponse,
SendHoldings,
PositionFileInfo
} from "../holdingsManager.dtos";
import { inject, singleton } from "aurelia-framework";
import { Router } from "aurelia-router";
import { EventAggregator } from "aurelia-event-aggregator";
import { GetPendingPositionMessage } from "../common/GetPendingPositionMessage";
#singleton()
#inject(Router, EventAggregator)
export class Pending {
router: Router;
positions: PositionFileInfo[];
client: JsonServiceClient;
eventAgg: EventAggregator;
constructor(router, eventAggregator) {
this.router = router;
this.eventAgg = eventAggregator;
this.client = new JsonServiceClient('/');
var req = new ListPendingHoldingsFiles();
this.client.get(req).then((getHoldingsResponse) => {
this.positions = getHoldingsResponse.PositionFiles;
}).catch(e => {
console.log(e); // "oh, no!"
});
}
openHoldings(positionInfo) {
this.eventAgg.publish(new GetPendingPositionMessage(positionInfo));
this.router.navigate('#/holdings');
}
}
Child.ts:
import { JsonServiceClient } from "servicestack-client";
import { inject, singleton } from "aurelia-framework";
import { Router } from 'aurelia-router';
import { EventAggregator } from "aurelia-event-aggregator";
import { GetPendingPositionMessage } from "../common/GetPendingPositionMessage";
import {
GetPendingHoldingsFile,
GetPendingHoldingsFileResponse,
Position,
PositionFileInfo
} from "../holdingsManager.dtos";
#singleton()
#inject(Router, EventAggregator)
export class Holdings {
router: Router;
pendingPositionFileInfo: PositionFileInfo;
position: Position;
client: JsonServiceClient;
eventAgg: EventAggregator;
constructor(router, eventAggregator) {
this.router = router;
this.eventAgg = eventAggregator;
this.eventAgg.subscribe(GetPendingPositionMessage,
message => {
this.pendingPositionFileInfo = message.fileInfo;
});
}
activate(params, routeData) {
this.client = new JsonServiceClient('/');
var req = new GetPendingHoldingsFile();
req.PositionToRetrieve = this.pendingPositionFileInfo;
this.client.get(req).then((getHoldingsResponse) => {
this.position = getHoldingsResponse.PendingPosition;
}).catch(e => {
console.log(e); // "oh, no!"
});
}
}
So the error happens when the child activates and attempts to send the request 'GetPendingHoldingsFile'.
Failed to load resource: the server responded with a status of 500 (NullReferenceException)
I have verified that this.pendingPositionFileInfo in the child is not null or empty and that on the server side, the object is not being received (it is null). I am new to Aurelia and not very experienced with Javascript so I must be missing something, any advice would be appreciated.
Edit 1
This seems to be something wrong with how I'm interacting with ServiceStack. I'm using version 4.5.6 of serviceStack with servicestack-client#^0.0.17. I tried newing up a fresh copy of the dto (PositionFileInfo) and copying over all the values from the parent view just to be sure there wasn't some javascript type conversion weirdness happening that I'm not aware of, but even with a fresh dto the webservice still receives a null request.
Switching from 'client.get(...)' to 'client.post(...)' fixed the problem. Apparently trying to serialize the object over in the URL was not a good plan.

Ember.js project - TypeError: session is undefined

I'm trying to run an Ember project that I had to upgrade it's packages, but now I run into deprecation issues.
My current issue is that when I press 'login' I see a TypeError: session is undefined message when I open the developer console in firefox.
I have no knowledge of Ember really, so to my very limited understanding is that there's a build javascript file that's based off an MCR architecture of little javascript files.
So here's the part of the big one:
define('genesis/controllers/login', ['exports', 'ember'], function (exports, _ember) {
exports['default'] = _ember['default'].Controller.extend({
loginMessage: "",
actions: {
authenticate: function authenticate() {
var credentials = this.getProperties('identification', 'password'),
authenticator = 'simple-auth-authenticator:jwt';
this.set("loginMessage", "");
var session = this.get('session');
session.authenticate(authenticator, credentials);
}
}
});
});
And this is the small one it's based off:
templates/login.js
import Ember from 'ember';
export default Ember.Controller.extend({
loginMessage: "",
actions: {
authenticate: function() {
var credentials = this.getProperties('identification', 'password'),
authenticator = 'simple-auth-authenticator:jwt';
this.set("loginMessage", "");
var session = this.get('session');
session.authenticate(authenticator, credentials);
}
}
});
I had to change Ember.ObjectController.extend to Ember.Controller.extend due to deprecation.
Assuming session is a service, you need to inject it into the controller in order to be able to use it. Without injecting, this.get('session') would return undefined.
Check this documentation on more details about dependency injection.
Turned out that during the upgrade I had removed one package from package.json named
ember-simple-auth-token, but I'll give credit to Charizard for letting me find it due to his answer.
I also had to make some tiny changes to the template file.
templates/login.js:
import Ember from 'ember';
export default Ember.Controller.extend({
session: Ember.inject.service(),
loginMessage: "",
actions: {
authenticate: function() {
var credentials = this.getProperties('identification', 'password'),
authenticator = 'authenticator:jwt';
this.set("loginMessage", "");
this.get('session').authenticate(authenticator, credentials);
}
}
});

Promise in Ember route model not resolving/updating

I'm using Ember Simple Auth and a service that gets injected into application controller to keep track of currently logged in user. I can use {{accountName}} for the currently logged in user in my application template by doing the following:
//controllers/applications.js
import Ember from 'ember';
export default Ember.Controller.extend({
session: Ember.inject.service(),
userFromSession: Ember.inject.service('session-user'),
accountName: Ember.computed('session.data.authenticated.userId', function(){
this.get('userFromSession.user').then((user)=>{
if (Ember.isEmpty(user.get('company'))) {
this.set('accountName', user.get('firstName') + ' ' + user.get('firstName'));
} else {
this.set('accountName', user.get('company.name'));
}
});
})
});
My session-user service looks like the following:
//services/session-user.js
import Ember from 'ember';
import DS from 'ember-data';
const { service } = Ember.inject;
export default Ember.Service.extend({
session: service('session'),
store: service(),
user: Ember.computed('session.data.authenticated.userId', function() {
const userId = this.get('session.data.authenticated.userId');
if (!Ember.isEmpty(userId)) {
return DS.PromiseObject.create({
promise: this.get('store').find('user', userId)
});
}
})
});
Now, a user has a company, and a company has opportunities. I would like to retrieve the company opportunities, based on the currently logged in user. How do I do this? In my opportunities route I have tried the following:
//routes/opportunities/index.js
import Ember from 'ember';
export default Ember.Route.extend({
sessionUser: Ember.inject.service('session-user'),
model: function(){
this.get('sessionUser.user').then((user)=>{
let companySlug = user.get('company.slug');
console.log(companySlug);
return this.store.findRecord('company', companySlug);
});
}
});
When using {{model.opportunities}} in my template, it just stays blank and looks like the promise never resolves. However, I can see the data populating in the Ember Inspector, as well as the expected output of my console logs. Further, when I do the following, it works fine:
//routes/opportunities/index.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function(){
let companySlug = 'known-company-slug';
return this.store.findRecord('company', companySlug);
}
});
Which means that the problem lies with model not resolving/updating for some reason. What am I doing wrong here?
Okay so I was trying to get the company model when I already had access to it through the sessionUser service.
//routes/opportunities/index.js
import Ember from 'ember';
export default Ember.Route.extend({
sessionUser: Ember.inject.service('session-user'),
model: function(){
return this.get('sessionUser.user').then(user => user.get('company'));
}
});

Ember Simple Auth transition after login

I have login code on my application route, as per examples in the docs, but the call to authenticate does not seem to return a promise. The response I get in 'then' is undefined. Therefore the transition does not work. I have to manually refresh the page, and then the top redirect is called.
import Ember from 'ember';
// Make 'session' available throughout the application
import ApplicationRouteMixin from 'simple-auth/mixins/application-route-mixin';
export default Ember.Route.extend(ApplicationRouteMixin, {
redirect: function () {
this.transitionTo('orders');
},
actions: {
authenticate: function () {
var data = {
identification: this.controller.get('identification'),
password: this.controller.get('password')
};
this.get('session').authenticate('simple-auth-authenticator:oauth2-password-grant', data).then(
function(response) {
console.log(response); // undefined
this.transitionTo('orders'); // can't call on undefined
}
);
},
}
});
My issue was 'this' inside the function call was the wrong object. Solved by using var _this = this;
I'll post the full working code.;
import Ember from 'ember';
// Make 'session' available throughout the application
import ApplicationRouteMixin from 'simple-auth/mixins/application-route-mixin';
export default Ember.Route.extend(ApplicationRouteMixin, {
redirect: function () {
this.transitionTo('orders');
},
actions: {
authenticate: function () {
var data = {
identification: this.controller.get('identification'),
password: this.controller.get('password')
};
var _this = this;
this.get('session').authenticate('simple-auth-authenticator:oauth2-password-grant', data).then(
function(response) {
console.log(_this.get('session')); // this correctly gets the session
_this.transitionTo('orders');
}
);
},
}
});
The promise returned by the session's authenticate method doesn't resolve with a value. You can access data that the authenticator resolves with via the session's secure property, e.g. this.get('session.secure.token)'.

Ember.js Railscast #410 undefined is not a function TypeError: at RandomRaffle.EntriesRoute.Ember.Route.extend.setupController

I'm following the Ember.js Railscast episode 410. When I change my router.js file from
RandomRaffle.EntriesRoute = Ember.Route.extend({
setupController: function (controller) {
controller.set('content', []);
}
});
to this
RandomRaffle.EntriesRoute = Ember.Route.extend({
setupController: function (controller) {
controller.set('content', RandomRaffle.Entry.find());
}
});
I get the error:
Error while processing route: entries undefined is not a function TypeError: undefined is not a function at RandomRaffle.EntriesRoute.Ember.Route.extend.setupController
My models/entry.js file contains:
RandomRaffle.Entry = DS.Model.extend({
name: DS.attr('string'),
winner: DS.attr('boolean')
});
My controllers/entries_controller.js contains:
RandomRaffle.EntriesController = Ember.ArrayController.extend({
// newEntryName: "",
actions: {
addEntry: function () {
RandomRaffle.Entry.createRecord({name: this.get('newEntryName')});
this.set('newEntryName', "");
},
drawWinner: function () {
this.setEach('highlight', false);
var pool = this.rejectBy('winner');
if (pool.length > 0){
var entry = pool[Math.floor(Math.random() * pool.length)];
entry.set('winner', true);
entry.set('highlight', true);
this.get('store').commit();
}
}
}
});
javascripts/store.js
RandomRaffle.Store = DS.Store.extend({});
// Override the default adapter with the `DS.ActiveModelAdapter` which
// is built to work nicely with the ActiveModel::Serializers gem.
RandomRaffle.ApplicationAdapter = DS.ActiveModelAdapter.extend({});
What am I missing?
Providing your store is properly defined, you should create a model function in your route, similar to this:
RandomRaffle.EntriesRoute = Ember.Route.extend({
model: function() {
return RandomRaffle.Entry.find();
// This is deprecated. Latest versions of ember-data use the following:
// return this.store.find('entry');
// this method returns a promise that will
// carry the model data once it resolves
// This is internally passed as a param of `setupController`
},
setupController: function (controller, model) {
controller.set('content', model);
// this is the same as the default implementation, so if you're *NOT* doing
// anything different than this, get rid of `setupController` altogether
// the `model` param, is the return of the `model` function just above.
// It is returned a `promise` rather than data, and will be made
// available once the promise is resolved, materializing the records
// the param doesn't have to be called `model`, but the
// function above *HAS* to be named `model`
}
});
I am not 100% sure, but I believe the error may be happening because you are calling RandomRaffle.Entry.find() when it should be this.store.find('entry')
The models/entry.js and store.js files are correct in the original question. Plus...
router.js
RandomRaffler.EntriesRoute = Ember.Route.extend({
model: function() {
return this.store.find('entry');
}
});
entries_controller.js
RandomRaffler.EntriesController = Ember.ArrayController.extend({
actions: {
addEntry: function(name) {
//Create the entry record
var entry = this.store.createRecord('entry', {
name: name,
winner: false
});
// Save the changes
entry.save();
},
Also you may notice in your rails server log that there is a problem with the csrf token, this can be fixed by placing this code in the first few lines of the rails controller file (eg entries_controller.rb)
skip_before_action :verify_authenticity_token
A full working app of the Railscast project can be found at https://github.com/markwiggles/raffler

Categories

Resources