filter user input in angularjs - javascript

I built something in angular using ng-repeat
<ul class="messages">
<li ng-repeat="e in enquiries">
<img src="/img/avatar.jpg" alt="">
<div>
<div>
<h5>{{e.user}}</h5>
<span class="time"><i class="fa fa-clock-o"></i> {{e.created_at}}</span>
</div>
<p>{{e.post}}</p>
<div ng-if="e.is_replied == 'no'">Delete</div>
</div>
</li>
</ul>
This is to display the inputs by users. However i did not htmlentities to encode the user input but directly insert the user input into database such as Hack However i notice when i display this message using above code. it will still display the message as Hack instead of display a "hack" link. can i say in this case angular will auto sanitize the input? Should i still need to use "ng-bind-html"?

If your post content is HTML you will need to change to ng-bind-html:
<p ng-bind-html="e.post | to_trusted"></p>
Also you will need a filter to sanitize:
app.filter('to_trusted', ['$sce', function ($sce) {
return function (text) {
return $sce.trustAsHtml(text);
};
}])

Your best bet is the $sanitize service, part of the ngSanitize module. Use the ng-bind-html directive, which automatically uses $sanitize. ng-bind-html will insert your text as raw HTML, but only if it's in the ngSanitize white list of safe HTML. If you're absolutely sure the HTML is safe (e.g., if you sanitize it on the back end), there's a way to tell Angular to stuff it in as is, regardless of the white list.

Related

store formatted text in mysql using cakephp and angularjs

Currently i am trying to build an community page in which user can contribute there articles in well text format. My backend is cakephp and front-end is angular-js
How can i store text in well formatted html style for example input text which i want to store in Mysql is
<b> hello </b><br/>
<em>world </em>
and when i fetch text from table output must be like
hello
world
update:-
and it should also work for inline CSS if it is possible then it is great.
<div style="color:#D2691E">hiiii</div>
i don't need to implement fancy animation-css tag but it should support basic css.
thank you in advance
You can use the ngBindHtml directive, but before you must include the $sanitize service and put ngSanitize as a dependency of your application module.
Also implemented a trusted filter with the use of $sce which is a service that provides Strict Contextual Escaping services to AngularJS.
Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain contexts to result in a value that is marked as safe to use for that context.
Code:
angular
.module('myApp', ['ngSanitize'])
.filter('trusted', ['$sce', function($sce) {
return function(str) {
return $sce.trustAsHtml(str);
};
}])
.controller('myController', function($scope) {
$scope.myHTML = '<b>hello</b><br/><em>world</em>';
$scope.myHTMLStyled = '<div style="color: #D2691E">hiiii</div>';
});
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-sanitize.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<div ng-bind-html="myHTML"></div>
<div ng-bind-html="myHTMLStyled | trusted"></div>
</div>

How to bind html to an external component? (Angular)

We have consumed an external library with components we would like to use, one of the components is an alert modal, that is represented as so:
<alert dismissible="false">Enter your text here</alert>
It renders out:
<alert dismissible="false" initialized="true">
<div class="alert-inside alert-type-info" aria-hidden="false" role="alert">
<div region-container="content">
<span>
<span class="ng-binding ng-scope">Enter your text here</span>
</span>
</div>
</div>
</alert>
The way we have built our angular app we are using config variables to hold our content
AppConfig.EnterText= "Enter your text here";
In which case we would call alert as so
<alert dismissible="false">{{AppConfig.EnterText}}</alert>
The problem is we actually want to use some html markup to be put into the alert...
AppConfig.EnterText= "<strong>Notice:</strong> Enter your text here";
In which case, if we include the content between the tags, it will render the tags instead of processing them. I have tried
<alert dismissible="false" ng-bind-html="AppConfig.EnterText"></alert>
This results in the inner tags being replaced with the content...
<alert dismissible="false" initialized="true">
<strong>Notice:</strong> Enter your text here
</alert>
Anyone have suggestions?
To solve this problem, I believe you need to use ng-bind-html directive in conjunction with the $sce service. Have you tried injecting the $sce service into your controller? Once you do that, you can set your variable like this:
AppConfig.EnterText= $sce.trustAsHtml("<strong>Notice:</strong> Enter your text here");
I was able to resolve the issue with the following:
<alert dismissible="false">
<span ng-bind-html="AppConfig.EnterText"></span>
</alert>

Iframe video from Angular Array using ng-bind-html

I'm having some trouble getting an iframe to work through using ng-bind-html. I have all my data inside an array. I've been mainly using ng-bind-html to keep it all in one place. I can't seem to get it to work with iframe's though.
Here is an example of what I'm trying to do.
xPlunker
As you can see it isn't really doing anything.
You need to use $sce:
$sce ("Strict Contextual Escaping") is a built-in angular service that automatically sanitize content and internal sources in templates.
injecting external sources and raw HTML into the template requires manual wrapping of$sce.
In this example we'll create a simple $sce sanitation filter:.
Demo
.filter('sanitizer', ['$sce', [function($sce) {
return function(content) {
return $sce.trustAsResourceUrl(content);
};
}]);
Usage in template
<div ng-repeat="item in items">
<!-- Sanitize external sources -->
<iframe ng-src="{{item.youtube_url | sanitizer}}">
<!-- Sanitaize and render HTML -->
<div ng-bind-html="{{item.raw_html_content| sanitizer}}"></div>
</div>

how to process html using angular and bindings (?)

here is my testing page :
<div ng-controller="test">
<input ng-keyup="asIwrite($event)" />
<p id="entityContent"></p>
</div>
and my controller :
EntitiesApp.controller('test', ['$scope', function ($scope) {
$scope.asIwrite = function ($event) {
$('#entityContent').html($event.srcElement.value);
}
}]);
this is actually working, if i write click in the input, the paragraph will hold the clickable url (processed html).
I am using jQuery to update the content of the paragraph as to show html element as they render in the page..
But using jQuery is a work-around in my opinion.
I want to achieve that using just Angular. How can I do ?
note : sure I can sweep jQuery off my project and use innerHTML of the
element but I want to know the way of doing that in Angular with
bindings. I used ng-bind on a paragraph element but that just
render the value of the textarea as is, no html process is performed.
See working example below.
You are right by doubting using jQuery is the right thing to do, and as you would expect it is not. The angular way to do that is register your input into the scope using ng-model, and the way to display it is using the ng-bind-html directive. (or simply ng-bind if it was simple text with no HTML)
However, Angular will not allow HTML binding by default as it could be a security issue. If you are sure about what you write, you can use $scope.trustAsHtml as showed in my example.
angular.module('test', [])
.controller('test', ['$scope', '$sce', function ($scope, $sce) {
$scope.trust = function(content) {
return $sce.trustAsHtml(content);
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="test">
<input ng-model="content"/>
<p ng-bind-html="trust(content)"></p>
</div>
You probably have tried to do something like this but the content doesn't come out as html
<input ng-model="input" />
<p id="entityContent" ng-bind-html="input"></p>
You need to ensure strict context escaping as described here:
https://docs.angularjs.org/api/ng/service/$sce
Please keep in mind what you're saying you want to do is explicitly prevented by angular developers as a way to mitigate XSS attacks
You don't need to do that, angular is simplier than that.
<div ng-controller="test">
<input ng-model="variable1" />
<p id="entityContent">{{variable1}}</p>
</div>
Angular binds variables automatically. When the input's value change, the new value will be printed.

Get Angular ngRepeat InnerHTML

I would like to know how to get the Full, Plain HTML of an Angular ngRepeat.
I need it to create reports, alert part of code etc.
I used the $compile and I've been able to get the HTML of simple tags by compiling
<p>I am {{surname}}, {{name}} {{surname}}</p>
and what I got is
<p>I am Bond, James Bond<p>
But when I try to do the same with
<p ng-repeat="number in array">{{number}}</p>
I only get the Angular comment saying
<!-- ngRepeat -->
Instead of the series of paragraphs.
Please check this Fiddle for examples.
In order Angular to compile ngRepeat directive it must be in DOM. Angular finds corresponding comment and replaces it with actual HTML structure.
So all you need to do is to append compiled comment node to DOM and after it's rendered you can retrieve HTML.
$scope.html = $compile('<p ng-repeat="el in arr">{{el}}</p>')($scope);
document.getElementById('app').appendChild($scope.html[0]);
Demo: http://jsfiddle.net/d4p0qLx2/2/
And in the next digest cycle you can get rendered HTML: http://jsfiddle.net/d4p0qLx2/4/

Categories