TinyMCE - Making all formats and style output as classes - ruby-on-rails-3

In order to avoid XSS, I am sanitizing the input. If I allow certain attributes such as style, I am uncertain and was unable to find a definite answer if allowing style in sanitize will prevent xss or not. (the examples give in the answer are not permitted by sanitize and do not cause XSS)
So for instance, If the user chooses the left-to-right text direction or right-to-left text direction button the output will be
<span style="direction:ltr"> user text </span>
I want to avoid that and somehow make it like this
<span class="LTR"> user text </span>
and I'll change the LTR classes afterwards in different css.
I tried changing the tinymce.yml but the best I could do is break the form and not making it work.
Can someone give me an example on how to do this so I could do this for all formats and styles? (or is it better to use nokogiri or similiar to parse it and change it myself?)

I would do something like the following
var editor = tinymce.get('your_editor_id');
$(ed.getBody()).find('[style=direction:ltr]').attr('style','').addClass('LTR');
You may use the tinymce setup configurationparameter together with an event on which you want to perform this action:
tinyMCE.init({
...
setup : function(ed) {
ed.onKeyUp.add(function(ed, evt) {
$(ed.getBody()).find('[style=direction:ltr]').attr('style','').addClass('LTR');
});
}
});

Related

aurelia: properly sanitizing innerHTML-bound data

I am perfectly aware that I can sanitize innerHTML-bound data using:
<div innerhtml.bind="someData | sanitizeHTML"></div>
However, based on my observations, this sanitization only removes <script> tags. It doesn't protect the user from event-driven content such as:
"Hi! I am some HTML-formatted data from the server! <button onclick="getRekt();">Click me for butterflies!</button>"
Is there a better way to prevent ANY type of javascript or event callbacks from being rendered on the element?
The sanatizeHTML value converter is a very simple sanitizer, and only remove the scripts tags. See the code here.
You can create your own value converter with a more complex santizer. Check this answer for more details about how to sanitize html in a browser.
But don't forget to never trust the browser, if you can it's better to sanitize the html in the server side before to send it to the browser to display it.

how to create a pdf editor for grails

In my Grails project I'm using the PDF plugin to generate PDFs from gsp page.
It works well, but I would like to add more functionalities to users, so I would like to allow user to edit the PDF basic template (defined in a gsp page), in particular I would like to allow the editing of the text inside the template and store it somewhere.
Anybody knows how could it be done?
If you only want to change the text, you could store the edited text in a database with the user id and loading it into the gsp page instead of the standard text.
If you also want to change the style of the page you could try to store the whole gsp page in the database and let the user editing it with an HTML Editor.
that's how i would start with, maybe someone has an better idea
The underlying components of the pdf plugin don't strictly require a .gsp file. It simply uses .gsps rendered as strings and feeds those into the flyingsaucer lib. So you could use a WYSIWYG type editor to allow users to create html snippets, save those strings somehow and then feed those though to the flyingsaucer libs yourself. just look into the included service methods of the plugin for an example. That might sound scary, but it really isn't very complicated.
You might want to wrap the user generated content with some of your own HTML markup for sanity and styling purposes of course, but the idea you are going for is entirely doable.
You could have a GSP that behaves of two different ways. First of all the GSP will be rendered in a Editable state. In this state the user could do some edits in some parts of the GSP. After that, the GSP will be rendered in a Preview state, where user could check the modifications that he has done in the previous step (nothing can be edited in this state). Finally, the GSP will be rendered as a PDF (using Grails Rendering Plugin).
Note that user will not edit the GSP itself. You need to allow him to edit through HTML elements as Text Areas, for instance. In this case we're using an WYSWYG editor. This editor allows the user to put text as Bold, Italic, etc.
Therefore, the most important step of this solution is to distinguish the two states in the same GSP. To do that you can use a boolean variable (called editing, for instance). This variable, if true, will render the GSP with the elements that will allow him to perform changes in the document. For other side, if the editing variable is false, the GSP will be rendered just with texts, not allowing any kind of editing.
The user could Check or Uncheck checkboxes (to show or hide some part of the document) and write or change texts in the Text Areas elements.
Below I'll show how this solution works.
GSP
The GSP is a template GSP and is called _quote.gsp
The piece of code below shows the use of the editing variable. Note that if editing = true, then a textarea is rendered and user can edit the text. There is a standard text that can be changed.
The post variable keeps what user has done after the editing phase. We use JQuery serialize to get all paramaters and pass it to a Grails Controller.
<p>
<g:if test="${editing}">
<pgs:textArea html="true" autosize="true" name="fraseInicial" rows="2" cols="80">
${post?.fraseInicial?post.fraseInicial:"Conforme sua solicitação, a empresa tem a satisfação de informar-lhe os métodos e preços."}
</pgs:textArea>
</g:if>
<g:else>
${post.fraseInicial}
</g:else>
</p>
pgs:textArea is a specific taglib of this system and is used to render a WYSWYG editor, you can replace it for a simple TextArea HTML element.
An example with checkbox:
<g:if test="${editing || post.temPrazoAnalise}">
<h1>
Teste teste
</h1>
<g:if test="${editing}"><g:checkBox name="temPrazoAnalise" value="${!post?true:post?.temPrazoAnalise == null?false:true}"/></g:if>
<g:if test="${editing || post.temPrazoAnalise}">
<p>Teste teste teste </p>
</g:if>
</g:if>
Controller
The previewQuote() is called from an AJAX call that serializes (via JQuery) all parameters of GSP.
The back() action allows the user to back to the editing state from the preview state. This is the reason why we set session["paramsReport"] = params inside previewQuote(). Doing this way it's possible to use session["paramsReport"] inside back() and restore the values changed by the user.
def editQuote() {
def quote = Quote.get(params.id)
render(template: "/quote/report/quote", model: [editing:true, quote:quote])
}
def previewQuote() {
Quote quote = Quote.get(params.id)
session["paramsReport"] = params
render(template: "/quote/report/quote", model: [quote:quote, post:params])
}
def back() {
def quote = Quote.get(params.id)
if (session["paramsReport"]) {
render(template: "/quote/report/quote", model: [editing:true, post:session["paramsReport"], quote:quote])
}
}
def generateQuote() {
Quote quote = Quote.get(params.id)
def f = new File(grailsApplication.mainContext.servletContext.getRealPath("/app/temp/${quote.code}.pdf"))
if (f.exists())
f.delete()
f.withOutputStream { os ->
pdfRenderingService.render([template: '/quote/report/quote', model: [quote:this, post:session["paramsReport"], pdf:true]], os)
}
}
This solution was developed by wanderson-santos (https://stackoverflow.com/users/128857/wanderson-santos) and me.
I hope you understand the overall idea of the solution. I understand that could be a bit complicated at a first view. Anyway, is a solution that allows flexibility for this kind of requirement (i.e. allow the user to customize a report before the PDF is generated).

Typeahead / Select2 support for Bootstrap 3

I'm building a google-style text box that auto-completes typed text.
Using typeahead with typeahead.js-bootstrap.css:
$(document).ready(function() {
$('#op1').typeahead({
remote: '/search/%QUERY',
});
});
<input type="text" id="op1">
it worked but there are two problems:
I could not customize it. Whenever I make any significant style changes, or use bootstrap's form-control class for input element: the text box gets completely messed up.
The auto-completed ("hint") text was written above the typed text so I whatever color I set for the hint was the color of the entire text! I tried giving the hint a negative z-order but then it was not displayed at all.
I've tried Typeahead AND Select2 auto-completion libraries with my Bootstrap 3 template, and so far the only thing I was able to work out-of-the-box without completely ruining the layout was the above code
If anyone can solve these problems, or otherwise recommend a full CSS + JS typeahead solution for Bootstrap3, I'd be grateful :)
It gives you completely easy way to customise the look with formatresults. You can even write full html view for your results. and to customise the look of input box apply a class to the wrapper for your search box and override select2 rendered css(load the page and check from browser that from where that style is coming).
http://ivaynberg.github.io/select2/
I made a full featured customised search with this.
There is now a fork available for select2 that supports Bootstrap 3.
http://fk.github.io/select2-bootstrap-css/
https://github.com/fk/select2-bootstrap-css#readme

DHTML - Change text on page using input field

I need to create a code to change an example text to a user-defined value when the user types in an input field (Similar to the preview field when writing a question on Stack Overflow).
This needs to be achieved without the use of HTML5 or Flash as the users will be running IE8, not all will have Flash plug-ins installed.
As such I have started by looking at DHTML to achieve the desired effect. Currently I can change the example text when a user types in the input field but only to a pre-defined value ("Example" in the code below), how should I edit this code to display the user-defined value?
JS
function changetext(id)
{
id.innerHTML="Example";
}
HTML
<form>
Content:<input type="text" id="input" onkeyup="changetext(preview)" />
</form>
<p id="preview">No content found</p>
You need to have something like this in the function:
function changetext(id){
var info = document.getElementById('input').value();
id.innerHTML = info;
}
This js is not fully correct. I would highly recommend you start using a javascript library like jQuery. It makes this a menial task.
Edited:
jQuery will work in IE8 just fine. in jQuery you will not need to attach js to your input. The code would look like this.
$('#input').click(function(){
$('#preview).html(this.val());
});
It is a lot cleaner and doesnt have js in the html.

Safe hidden text in HTML?

I need to have some hidden text in HTML to parse as text when i read an actual HTML file
I used to include my text in hidden div using style but i knew that may record us as spammers in SEO
.hideme {
position : absolute;
left : -1000px;
}
Can i have this content as commented text in the HTML ?
will that be safe as i know that SEO crawlers ignores the comments in HTML
<!-- my hidden text -->
Please advice
The search engines only care about hidden text when it is used to manipulate a page's rankings. Typically this is defined as content that is presented to the search engines that is not presented to users. So if you hide text so users can't see it but crawlers can you will find yourself having issues with Google. An example of when hiding text is good is when you use display:none to hide dynamic content and then use JavaScript or CSS to display the content when an action is performed (i.e. mouseover, etc).
If you place this extra content within comments as you suggest in your question you will be fine as this content is not available to users and search engines ignore comments.
Try to avoid "hide" in naming your CSS class.
But the best way is to avoid hidden text by finding easy and creative ways to add the text to the content of a web-page without seeming like spam.
You can't parse html comments so instead use a hidden field:
<input type="hidden" value="my text" name="my_hidden_field/>
Some people for SEO doing this :
.hideme {
width:0px;
overflow:hidden;
text-indent:-99999px
}
Why you do not use <meta> tags ?