ui-router structure for restricted admin panel - angularjs

Im building an app with AngularJs and ui-router. It's an admin panel with this structure:
Not authenticated
Authenticated
Admin panel
Client panel
For each of the authenticated states, the app needs to load different content and give access to different information, for example:
Admin: Can see a list with all clients, products, etc...
Client: Can see only his products, tickets, etc...
When the user log in I check if he's admin or client and then, with a lazyload, I load only the modules he needs. For example, client doesn't need the module to show the list of all clients.
This is the structure I have so far:
-index.html -> view:main
--login.html
--error.html
-app.html -> view:app
--restricted.html
--notFound.html
-app_adm -> view:app-adm -> lazyload admModule.js
--home_adm.html
--listClient.html
--listProducts.html
--listFinancial.html
etc...html
-app_cli -> view:app-cli -> lazyload cliModule.js
--home_cli.html
--userData.html
--products.html
--tickets.html
etc...html
index.html
<div ui-view="main"></div>
app.html
<nav>
[..content here..]
</nav>
<div ui-view="app"></div>
<footer>
[..content here..]
</footer>
app_adm.html
<div ui-view="app-adm"></div>
app_cli.html
<div ui-view="app-cli"></div>
It feels like using those 2 extra app (adm and cli) are not quite right, but until now it's the only I found to load the files only where I need.
Is there a better way to improve this structure?
Note: I tried to set the state app-adm and app-cli to be a state without templateUrl and use the same view as the state app but it didn't worked.

I have the same application structure and what I did is just bundled absolutely all templates in a bundle with e.g. gulp. Then I dynamically check if the url accessed by user is allowed (I have a notion of applet, e.g. apllet "client", "server"). This is stored in the local storage and user can access bad url's anyway by e.g. typing them in the browser. If it's not allowed, then there is a "forbidden" page or redirect to logon depending on your needs.
Of course most important part from the security point of view is that all the corresponding API calls are protected, so you can never trust on UI for security.
If you don't want to load all templates, then you can dynamically determine the bundle that you need, e.g. "client" bundle or "admin" bundle and load it.

Related

Rendering Just one module/state of Angular app

I've angular app with lots of states and modules etc. Now, I want to send a link to the user. When user'll hit this url, I want to redirect him to a new tab rendering only that particular state (specified in URL) i-e I don't want anything else to be visible to the user. Or you can say, I want to open a popup window rendering that particular state's html in popup window . This is the approach that comes to my mind to sort it out.
Ps. There are Rest APIs at the backend which I am calling through angular resource service to bind data with the model of the views
Option
I've rest APIs on backend, So, I was thinking to developing s separate Nodejs application, And I will send nodejs application url to the user and in the default/home route I'll call backend API and, the returned resultset will be rendered in html file within nodeJs application and this way, I'll render the corresponding data to user's browser window.
This is the flow for that
I don't know if that is right or clever approach. Please suggest me what will be the best approach to sort it out.
Thanks in advance.
This is what my app looks like
Everything in the left side-nav is a module and clicking on this I am routing to a different state. I am using angular-material and lots of other dependencies in this project.
And this is what I want.
I'll refer a link to the user for example www.myapp.com/specificpage.html. And hitting this url, a new tab/popup will be opened rendering state defined in the same app but with some non-editable url. And it should like.
There are multiple ways to achieve this and each approach has advantage and disadvantage. You have to choose depending on requirement and architecture. Details are below-
Create a separate app - You can do it through separate code base or use the module based build process and include this module only for new app.
Divide application is two part, public pages and private pages - Include this page and required APIs for this page in the public modules for your app.
Send token in the link - If you want to make secure page, send short lived token in the eMail and validate token on the server before displaying page to the user.

Grails 3 - Restrict html templates to logged in users

I am using Grails 3.1.4 together with AngularJS.
Certain sections on the page are for logged in users only and I want to restrict access to the according html templates, so only they can access them.
I have set up the Spring Security so that access to those templates is restricted.
The problem I encounter is, that it appears that all the html templates are loaded when the page is loaded the first time. At that moment the user is not logged in, thus the server returns a 401 error.
Once the users is logged in and tries to navigate to the restricted page, angular checks the template cache, realizes nothing is there and returns a 404 error.
When I look at the index.html in the developer tools, I can see, that the asset pipeline includes a script tag for each template, so all the templates are loaded at the initial page load.
Is it somehow possible, to have the templates loaded and cached dynamically when they are needed for the first time?
You might allow HTML templates to be accessible to all. For restricting the content, you might need to implement Spring Security token based Authentication and check accordingly what content should be visible to whom.
Reference : http://alvarosanchez.github.io/grails-spring-security-rest/2.0.0.M2/docs/index.html

AngularJS - Project Structure - Mixing public and private pages

I intend to build a typical information website that has a number of pages that do not require authorization to view them, however I also want to have a private section for staff to log in. For simplicity I am hoping I can do one Web API project and have everything within it to simplify my publishing to azure, simplify domain names and certificates etc.
Is it ok for me to have index.html as a container and use ui-router to navigate through even the public pages or would it be better to have all public pages as full html files and do typical href navigation between them?
Below is the possible structure I was thinking of
app/ -> all angularjs stuff including private views and controllers
Models/
Controllers
Index.html -> public home page
public/ all public pages
What I am trying to achieve is that all public views can be accessed via http but once the login page is accessed all traffic must from then on be https, does anyone have any experience of this?
Update:
I have decided to force https for all pages, does this take the structure worry away in that everything just goes under app?
Best way to keep this is as a full Angular SPA, using ui-router to move between views instead of having static pages (even if your partial views are just plain HTML without functionality). You can affect the UX by alternating between dynamic routing with Angular and typical old href navigation. The less the you make the user reload pages, the better user experience he/she will get, plus you must be consistent in the way the application flows overall so the user doesn't have bad impressions of it.

Taking server path into account in angular route

I am enhancing an ASP.NET MVC application with angularJS for selected pages. The primary means of navigating the site is still full page request, but some pages contain angular views and associated controllers for interactivity.
Currently, I achieve this by having something like this in the server side view:
<div ng-controller="ExampleCtrl" ng-include="exampleview.html"></div>
However, I would prefer to not inline controller and template definition like that and handle this through routing instead. However, angular routing only uses the client side of the URL (i.e. the parts after the first #). For various reasons, the page URL should remain http://domain.com/Example/Action instead of http://domain.com/Example/Action/#/example (this is just ugly) or http://domain.com/#/example (this will not work because I actually need the server side view as well).
Is there a way to make angular routing take the whole URL path into account instead of just the client part (and works in IE9)?

Server (IIS) logging for a single page web app built in AngularJs

I have a single page web app which has close to 10 different sections like
discussions
profile
video
etc , each of them have their states in the router as , it has its own controller and template and the urls are like
1. http://myapp/#/discussions
2. http://myapp/#/profile
3. http://myapp/#/video
when the angular app loads all the templates and js files are downloaded and at IIS only one request is made ie:
http://myapp/
but the things after '#' don't get passed to server. The UI router replaces templates at the client side but I want to track how many users visit the particular sections of my web app.
I cant do that from IIS logs as no resources are requested for individual sections in short i am expecting a log entry in IIS as below when a user visits discussion section
http://myapp/discussions
please let me know if I am correct in this approach or should i follow some other method.
A single page app, by definition, only makes an initial request to the server (IIS) to retrieve HTML and javascript. Subsequent interaction with your app is all handled by the javascript you loaded initially.
You won't be able to rely on your web server for tracking this. Instead, you should find something that can fire events from the javascript side, such as Google Analytics.

Resources