AngularJS how can I hide important DATA - angularjs

I just want to ask what would be the best way to hide sensitive data using anugularJS.
I am developping a VOD (Video On Demand) app in which I have to make movies' links hidden and not accessible by users.
For example, I get this JSON from backend using $http inside a moviesFactory:
{ "title": "movieTitle", "link": "www.some-provider-link.com/movie-link.mp4"}
And when I need to show the video, I put this JSON in my scope like that:
$scope.movie = moviesFactory.getMovie().then(callbackOk, callbackNonOk);
My problem is since the scope is accessible from user using chrome extensions or even angular.element(document.getElementById('anElementId')).scope()
everyone can access my scope and see the links.
So what am I doing wrong? ANd how can I hide those data?

You can't directly by this way, because javascript is executed in client side (and you have not full control of the sources you provide to the clients).
And sharing (encrypted/obscured or not) your complete files url ('www.some-provider-link.com/movie-link.mp4') it's NOT a good idea, if you are concerned of the privacy of those files.
You should consider including some sort of authentication (like tokens) and make an API in your server that gives you all the data you needs (like .mp4 files) as a stream of bytes, when a user is authenticated.

Related

Best way to load customer parameters in a multi-tenant angularJS application

We have a multi-tenant Angular JS single page application. The routing for the application uses a customer identifier as part of the URL - #/home/<KEY> or #/search/<KEY>/<search term> for instance. In theory the first page served could be of any type. Each page calls an API using the customer key and other values picked up from the URL to get data for the page. So far so good.
We have some parameters - a logo, copyright statement, default language (for internationalization) - that can be loaded using a separate API call that also uses the customer KEY. These parameters need to be available as strings in partials, to drive the internationalization and perhaps in controllers.
The question is where to call the API to get these parameters and how to set them / make them available for the rest of the app. I have looked at a bunch of questions in this general area but can't find a concrete suggestion. Should we use a config in app.js? Call another script from index.html?
Appreciate people's advice.
The right place would be to make an API call immediately after authentication to get the various Customer specific configuration data like the Customer settings for logo, language and then put them in the session storage of the browser.
I have done an implementation using Microsoft ADAL js as per the documentation given here. https://github.com/AzureAD/azure-activedirectory-library-for-js/blob/dev/README.md.
You can do this Api call in the login success event handler or similar ones in angular.
Example:
$scope.$on("adal:loginSuccess", function () {
$scope.testMessage = "loginSuccess";
});
HTH

URL handling in a Hypermedia (HATEOAS) driven AngularJS application

We are looking for some advice on handling URLs (and the state related to each URL) in a web application backed by a HATEOAS REST API, more specifically on
how to avoid having the web application URLs coupled with the REST API URLs
how to handle multiple resources in a single view
But let me first provide some more context:
We are building an Angular web application on top of a REST layer with Hypermedia constraint. (Note: I prefer simply using the term 'Hypermedia (constraint)' over HATEOAS).
As dictated by the Hypermedia constraint, the available actions and links in the application at any point in time are provided by the REST API. So the web application should not contain any hardcoded urls of the REST API, except for the 'root' (assuming that concept really exists in a REST API).
On the other hand, each page in the web application needs to be bookmarkable. So we cannot create a black-box application (with a single url and all state changes handled in the SPA without changing the URL). This means the web application also has its URL space, which needs somehow to be mapped to the REST API URL space. Which is already a conflict with the Hypermedia idea.
In the Angular application we use UI Router for handling application state. Here is how we got it working:
We only define states, no URLS
We defined a $urlRouterProvider.otherwise handler that will map the current web application URL to the corrsponding REST API URL, retrieve the representation of the resource that corresponds with that REST URL and pass it to the controller (in $stateParams).
The controller can then use the data (and links and actions) in the representation, just like it would if it would have made the REST call itself (or through a service)
So far so good (or not really) because there are some downsides on this approach:
The Web application URLs are mapped to the REST API URLs, so both URL spaces are coupled, which conflicts with one of the basic assumptions of using Hypermedia constraint: we cannot change the REST API URLs without having to change the web application.
In the $urlRouterProvider.otherwise handler we retrieve the representation of the current web app URL. But in some cases we have two resources in a single view (using UI Router nested states): for example a list of items and a detail of a single item. But there is only a single URL, so only the representation of the item detail is retrieved and the list of items remains empty.
So we would love to hear some suggestions on how we could improve on our approach in handling the two URL spaces. Is there a better way to make the REST API dictate the (available) behaviour of the web application and still have bookmarkable URLs in the webapplication? Because now we have some kind of hybrid approach that does not feel completely right.
Thanks in advance.
Regards,
Luc
that's a tough setup. Roughly you want bookmarks into your API, and RESTful systems somewhat discourage bookmarks.
One possible solution is a "bookmark service" that returns bookmark (bit.ly like) urls for the current resource being presents that are guaranteed to be fowards compatible because as you may change the canonical url structure, the bookmark service can always translate the bit.ly like url into the canonical url. Sounds complicated, but we see this all the time and we call them SEO urls eg: /product-name/ maps to products/ today, but may be /catalog/old-products/ tomorrow.
How you match that up to a UI that shows 2 resources the first being a list of summary like resources, and the second being a specific resource get's really tricky. I would expect such a page to know contain the state of what's it's displaying in it's url (probably in the fragment). As such since it's [likely] the controller that processing such commands it probably needs both (the list resource and the expanded resource) as input. I bet the url would look something like:
list=http://path/to/list/results&expand=http://self/link/of/path
So the last part you have is to make sure that works going forwards. Again this is the bookmark problem. What i may suggest if you don't want to build a bookmark service is that given you want to have such bookmarks you need to transition people to the new URLs. When a request is made to http://path/to/list/results and you want to switch that over you should be 301 redirecting them to the new canonical url and the app should be updating the bookmark. such a redirect can include the &flag=deprecate_message param to trigger the presentation in the UI that the client's bookmark is old and should be replaced. Alternatively the response can be internally forwarded and the deprecation flag & canonical (or latest) link included in the response to the old URL. This causes a phased transition.
In summary: I have yet to see HATEOAS be a cure all for backwards & forwards compatibility, but it's much better than the existing techniques. that said you must still make decisions in v1 of your API about how you want your users to move to v2.

The best way to pre-populate remote data in AngularJS app

In my AngularJS app, I need to retrieve multiple collections of static data from remote REST endpoints. Those data collections will be used throughout the entire application life cycle as static lookup lists. I would like for all those lists to be populated upon the initial application startup, and to be retained and made available to multiple controllers. I would prefer not to load any additional data dynamically, as one of the assumptions for this particular app, is that, once loaded, any further network connections may not be available for a while.
It is OK to take an initial hit, as the users will be preoccupied by reading a static content of the first page anyway.
I was thinking of making this mass loading a part of the initial application run block, and stick all this static data into various collections attached to the $rootScope (which would make that available everywhere else)
What is the best way to handle this requirement?
Interestingly enough, I just wrote a blog post about extending the script directive to handle this very scenario.
The concept is simple. You embed JSON data in your page when it loads from the server like so:
<script type="text/context-info">
{
"name":"foo-view",
"id":34,
"tags":[
"angular",
"javascript",
"directives"
]
}
</script>
Then you extend the script directive so it parses the data out for you and makes it available to other parts of your application via a service.
if(attr.type === 'text/context-info'){
var contextInfo = JSON.parse(element[0].text);
//Custom service that can be injected into
// the decorator
contextInfoService.addContextInfo(contextInfo);
}
You can see a live demo of it here: http://embed.plnkr.co/mSFgaO/preview
The way I approach this is to use a service (or a collection of services I nest), and set caching to true in the $http get functions. This way the service can be passed into any controller you desire, having cached results available to you without the need for additional http requests.
I can try to put this into an example if this is unclear to you, let me know.
edit: you can either wait for the first call to this service to do this caching, or do this on app load, either way is possible.

How to remember loaded views/frames in Angular.js

I am currently working on a large enterprise web platform which loads different web applications (html/js/silverlight) as views so it is almost like a container or a framework for accessing different types of web applications.
We are currently reviewing the migration to Angular however there's one problem (at least) which we can't address.
in the current non-Angular version when a user loads Application-A from within the framework and let's say types "ABC" in a text box then he decides to navigate away and load Application-B and after using that application when navigates back to Application-A he can still see "ABC" in the textbox in other words he has "Persistent Workspace" so every app that he loads whether it be Silverlight or Html/JS has the ability to be kept loaded into the memory.
Regardless of the right or wrong of this approach can anyone think of the way this can be implemented in Angular? a simple overview is enough.
[UPDATE]
Please note that we are dealing with iFrames for each of the web apps we currently load, so there's no model that we can persist to the browser storage or elsewhere. if all our apps where html/js based then we would have no problems as we could serialize the state of each view but since some are in Silverllight we can't do that. hope this clarifies.
Thank you all.
You can always synchronize Angular's state with the local storage of the browser. So there will have to be a unique key for every field in every form and use something like this.
Alternatively, you can listen for the $routeChangeStart event (docs) from within each controller that cares to save status. Then the controller can decide to serialize its state (or not) to the local storage. On controller initialization, the saved state must be retrieved.
Solutions involving the browser's local storage will not affect the server but will not be available to the user when he/she uses another computer. Otherwise, you should listen to the route events as before, but synchronize the "persistent workspace" with the server (slower, more development time).

how to send/receive data securely in backbone.js

I have created RESTFUL urls that respond with some JSON data when fetched by backbone.
So a url like /lists responds with a json array of user-created lists. My want that if the url is accessed by address bar input like mydomain.com/lists, the json data is displayed in text on browser. I want the server to respond only if the url is accessed from within the application. Can somebody provide me some hints on how to achieve this?
Like #Thilo said, you're not going to be able to do prevent a person with the right tools to see what's coming across the wire, Firebug's console/net tabs already keep track of requests and show the contents of responses.
That being said, what you can do is check whether the HTTP_X_REQUESTED_WITH HTTP header is set to 'XMLHttpRequest', and only return the JSON in this case. Backbone makes an Ajax call so this will always be the case with the Backbone calls (in modern browsers). Again this won't help much except for people who type it into the address bar directly (and do a normal GET request) won't see the JSON.

Resources