Ember.JS, display views depending on the user role - mongodb

I am using Ember.Js to create a web application, I have User collection in my MongoDb, in User collection there is a Role attribute which can take two values, "admin" or "customer".
What I want to do is the following :
When someone logs in, he is going to be redirected either to the admin dashboard or customer interface, depending on his Role.
How can I achieve this ? what is the best practice ?
It is a good idea or I should better create a collection for admin and another for customer ?

I would personally make use of the Application route's afterModel hook.
export default Ember.Route.extend({
model: function(){
//I DK if you use Ember Data. I don't but this could be a store lookup.
return this.userService.getCurrentUser()
},
afterModel: function(resolvedModel, transition){
var user = resolvedModel;
if(user.role === 'ADMIN'){
this.transitionTo('admin-dashboard');
}else{
this.transitionTo('customer-interface');
}
}
});
You could then have different menu structures that only link-to admin and customer routes respectively or both. I'd also have a mixin that all of my other Admin only routes extend:
import Ember from 'ember';
export default Ember.Mixin.create({
beforeModel: function(){
var currentUser = this.modelFor('application');
if(currentUser.role !== 'ADMIN'){
//handle this howerver
this.transitionTo('unauthorized');
}
}
});
So your admin-dashboard route would look like:
import Ember from 'ember';
import AdminRoute from 'app_name/mixins/admin-route';
export default Ember.Route.extend(AdminRoute, {});

Related

Performing a state persistance in Aurelia Store

We have a basic app state that needs to be persisted upon the browser refresh. similar to vuex-state-persistance plugin. Here is the basic state code that needs to be persisted.
export const initialState = {
user: {
uuid: 'wedRfertYjsnjnakUiisdj878HBhsns',
name: 'Kiran Maniya',
scope: 'user'
}
};
Is there anything that can be used directly as a plugin or I need to write a custom plugin that persists the state in localStorage asynchronously? Also, how do we modularise the state when we have a complex and large state to manage?
Aurelia Store provides a built-in mechanism to persist state in localStorage.
So, if your initialState goes initialized in main.ts or main.js something like this:
aurelia.use.plugin('aurelia-store', { initialState: initialState });
Then in app.ts or .js you should register the localstorage middleware and perform a rehydration.
So, in app constructor, you could write:
import { localStorageMiddleware, rehydrateFromLocalStorage, Store } from 'aurelia-store';
import { initialState, State } from 'state';
...
constructor(
private store: Store<State>,
) {
store.registerMiddleware(localStorageMiddleware, MiddlewarePlacement.After, { key: ¨someKey¨ });
store.registerAction('Rehydrate', rehydrateFromLocalStorage);
}
Regarding modularization, maybe you should combine store and the EventAggregator to implement more complex scenarios.
Good luck

Using angular2-sails module for realtime communication using sockets

I would like to use sails.io.js with angular5, so I used angular2-sails module. I managed to connect angular to sails but I didn't manage to retrieve the events from sails.js, for example when a new document is created in database. Is there something to configure sails side ? I used this.sailsService.on("user").subscribe(data => console.log("event on user")). The get and post methods are perfectly working. Sails side I put
ioclient: require('socket.io-client')('http://localhost:1337'),
io: require('sails.io.js'),
In config/http.js, instead of
var io = require('sails.io.js')( require('socket.io-client') );
because else sails cannot load
I didn't write anything in config/socket.js
angular2-sails module is deprecated so I used the io variable from sails.io.js using a service :
import {Injectable} from '#angular/core';
function _window(): any {
// return the global native browser window object
return window;
}
#Injectable()
export class SocketService {
get ioSails(): any {
return _window().io;
}
}

Paths/links with unique ID's angular2

I'm creating a quiz making/sharing website using angular2 but am not sure how to share the quizzes. i was thinking of using each of my quizzes identifiers as URLs. The quizzes are made using forms and are saved on a docmentdb as JSON. they have unique ID's to identify them. Any ideas as to how i could do this?
Those URLs must be dynamically created, as new quizzes can be submitted and thereafter accessed.
You can use the same base url for your page with quiz, but differentiate quizzes by path parameter like:
quizsite.com/#/quiz/12 (12 being quiz id)
Inside your component you can read what path parameters are located in your url and their values by accessing ActivateRoute object:
Component
import { Component } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
#Component({
templateUrl: 'quizComponent.html',
})
export class QuizComponent {
constructor(private activatedRoute: ActivatedRoute){}
ngOnInit() {
// Reason for this being a observable is that you can watch
parameter changing (manually in url, or programmatically)
and without any page refresh, read new parameter and change you quiz
this.activatedRoute.params.subscribe(params => {
console.log(params.quizId);
// With this parameter you can make call to your REST API and return
data for that quiz
});
}
}

Modify routing in Sails to use something else than id?

I have a web app which talks to my backend node.js+sails app through a socket.
Default routes for sockets use id. As example
io.socket.get('/chatroom/5')
My app doesn't authenticate users and as result I want id's to be random, so nobody can guess it. However, id's are generated by mongoDB and aren't that random.
As result, I want to use some other field (a.e. "randomId") and update routing for this model to use this field instead of id.
What's the best way to do it?
P.S. It looks like I have to use policies, but still struggling to figure out what should I do exactly.
You aren't forced to use the default blueprint routes in your app; you can always override them with custom controller methods or turn them off entirely.
The GET /chatroom/:id method automatically routes to the find action of your ChatroomController.js file. If you don't have a custom action, the blueprint action is used. So in your case, you could define something like the following in ChatroomController.js:
find: function (req, res) {
// Get the id parameter from the route
var id = req.param('id');
// Use it to look up a different field
Chatroom.find({randomId: id}).exec(function(err, chatrooms) {
if (err) {return res.serverError(err);}
// Subscribe to these rooms (optional)
Chatroom.subscribe(req, chatrooms);
// Return the room records
return res.json(chatrooms);
});
}
If you don't like the name find or the param id, you can set your own route in config/routes.js:
"GET /chatroom/:randomid": "ChatroomController.myFindActionName"
Also, re:
Default routes for sockets use id.
those routes aren't just for sockets--they respond to regular HTTP requests as well!
I created a policy. This policy converts randomId (which is passed as :id) to real id and saves it in req.options.id (which Sails will pick up).
module.exports = function(req, res, next) {
var Model = req._sails.models[req.options.model];
var randomId = req.params.all()['id'];
Model.findOne().where({ randomId: randomId }).exec(function(err, record) {
req.options.id = record.id;
return next();
});
};
And I apply this policy to findOne and update actions of my controller:
ChatRoomController: {
findOne : 'useRandomId',
update : 'useRandomId'
}

Admin section in ZendFramework application

I have an application at the moment using Zend_Auth for user access. The site has an admin section where I want one user who has the role of admin in my database to be allowed access when he uses his credentials. Is Zend_Acl the only way to do this? As it seems a little complex for what I want to do or would there be any easier solutions to my problem?
I have had a think about this and I am now wondering if it is possible to have two auth controllers one for users and one for my admin section?
I did something like this recently. Create a front-controller plugin for the admin module that checks the user credential. Something like:
class Admin_Plugin_Auth extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
if ($request->getModuleName() != 'admin'){
return;
}
$auth = Zend_Auth::getInstance();
if (!$auth->hasIdentity()){
// send him to login
}
$user = $auth->getIdentity();
if (!$user->isAdmin()){ // or however you check
// send him to a fail page
}
}
}
I decided to go with the method of having a field of "is_admin" in my database if its set to 1 the user is an admin. I then use this code:
public function init()
{
$this->auth=Zend_Auth::getInstance();
if ($this->auth->getStorage()->read()->is_admin) {
$route = array('controller'=>'admin', 'action'=>'index');
} else {
$route = array('controller'=>'index', 'action'=>'index');
$this->_helper->redirector->gotoRoute($route);
}
}
This redirects the user from the admin area if they are not an admin and allows them access if they are an admin.. A lot easier to implement than ACL for the simple use in my application.