Sanitize HTML input using JavaScript server side and client side - javascript

I am making an attempt to create my own chatroom using npm, as it stands everything is working smoothly but my main concern is SQL injection or people entering HTML because it will parse anything entered. There is no form being used and the input button, text field and output are all controlled by JavaScript. below is the part of the HTML I am referring to.
<div id="wrapper">
<div class="bubble-container" ></div>
</div>
<div id="sendCtrls">
<input type="text" placeholder="Your message here" id="text">
<button id="myBtn">Send</button>
</div>
This is my .php file which contains all the JavaScript.
<script>
// -------------------------
//var name = prompt('What is your name?');
var name = "<?php echo $_SESSION['username']; ?>";
var bubbles = 1;
var maxBubbles = 60;
var sock = new WebSocket("ws://localhost:5001");
sock.onopen = function() {
var bubble = $("#wrapper");
bubble = $('<div class="bubble-container"><span class="bubble"><div class="bubble-text">\
<p><b>*** Welcome '+name+' to the chat!</b><br>\
These are the rules, please read & follow them.<br>\
1. Be polite in chat.<br>\
2. Keep personal disputes out of chat.<br>\
3. No advertising.<br>\
4. Do not ask to become a Moderator.\
</p></div></div>');
myChat(bubble);
sock.send(JSON.stringify({
type: "name",
data: name
}));
}
// --------------------------
var maxLength = 200; // chars per bubble
sock.onmessage = function(event){
console.log(event);
var json = JSON.parse(event.data);
var bubble = $('<div class="bubble-container"><span class="bubble"><div class="bubble-text"><p><strong>'+json.name+':</strong> '+json.data+'</p></div></div>');
myChat(bubble);
}
// ---------------------------
document.querySelector('button').onclick = function (){
var text = document.getElementById('text').value;
if(text != "") {
if (text.length < maxLength) {
document.getElementById('text').value='';
sock.send(JSON.stringify({
type: "message",
data: text
}));
var bubble = $('<div class="bubble-container"><span class="bubble"><div class="bubble-text"><p><strong>'+name+':</strong> '+text+'</p></div></div>');
myChat(bubble);
}else{
var bubble = $('<div class="bubble-container"><span class="bubble"><div class="bubble-text"><p>*** Your message exceeds '+maxLength+' characters!</p></div></div>');
myChat(bubble);
};
}
};
// --------------------------
var input = document.getElementById("text");
input.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
document.getElementById("myBtn").click();
}
});
// --------------------------
function myChat(bubble){
$("#msgText").val("");
$(".bubble-container:last").after(bubble);
if (bubbles >= maxBubbles) {
var first = $(".bubble-container:first").remove();
bubbles--;
}
bubbles++;
$('.bubble-container').show(250, function showNext() {
if (!($(this).is(":visible"))) {
bubbles++;
}
$(this).next(".bubble-container").show(250, showNext);
$("#wrapper").scrollTop(9999999);
});
};
</script>
I have not included the server script which is also just JavaScript but can do so if needed. PHP has no interaction with what is being submitted. 2nd question is, will I need to write anything server side to protect against SQL injection or to prevent HTML being entered?

Related

Getting to specific data in jQuery

I am trying to add an ability to change the contents of one of the columns in the data table (its data cells should be editable). I was using this tutorial as a reference:
https://www.youtube.com/watch?v=LbhVVN5ffi0
its source code:
https://github.com/divanov11/table-edit-backend
And so, I have the following functions in my template:
function edit_description(place){
var targetId = $(this).attr("id");
var value = $(this).text();
var targetIN = $(this).attr("identificationNumber");
$(this).unbind();
$(this).html(`<input class="description form-control" data-target="${targetId}" type="text" value=${value}>`);
$(`.description`).on('keypress', function(e){
if (e.which == 13) {
var target = $(this).attr("data-target");
var description = $(`#${target}`).text($(this).val());
save_description(description, targetIN);
return false;
}
})
}
function save_description(description, identification_number){
console.log('Saved!');
var user_input = {"identificationNumber":identification_number, "description":description};
update_description_POST(user_input);
}
After typing in for example "chipset" I get the following description's value:
<td identificationnumber = "1234" id="description-1234">chipset</td>
I would need the description's value to be just "chipset". How to achieve that?

Change liferay-ui:input-localized XML with javascript

I have the following tag in my view.jsp:
<liferay-ui:input-localized id="message" name="message" xml="" />
And I know that I can set a XML and have a default value on my input localized. My problem is that I want to change this attribute with javascript. I am listening for some changes and call the function "update()" to update my information:
function update(index) {
var localizedInput= document.getElementById('message');
localizedInput.value = 'myXMLString';
}
Changing the value is only updating the currently selected language input (with the whole XML String). The XML String is correct, but I am not sure on how to update the XML for the input with javascript.
Is this possible?
PS: I have posted this in the Liferay Dev forum to try and reach more people.
After a week of studying the case and some tests, I think that I found a workaround for this. Not sure if this is the correct approach, but it is working for me so I will post my current solution for future reference.
After inspecting the HTML, I noticed that the Liferay-UI:input-localized tag creates an input tag by default, and then one more input tag for each language, each time you select a new language. Knowing that I created some functions with Javascript to help me update the inputs created from my liferay-ui:input-localized. Here is the relevant code:
function updateAnnouncementInformation(index) {
var announcement = announcements[index];
// the announcement['message'] is a XML String
updateInputLocalized('message', announcement['message']);
}
function updateInputLocalized(input, message) {
var inputId = '<portlet:namespace/>' + input;
var xml = $.parseXML(message);
var inputCurrent = document.getElementById(inputId);
var selectedLanguage = getSelectedLanguage(inputId);
var inputPT = document.getElementById(inputId + '_pt_PT');
inputPT.value = $(xml).find("Title[language-id='pt_PT']").text();
var inputEN = document.getElementById(inputId + '_en_US');
if (inputEN !== null) inputEN.value = $(xml).find("Title[language-id='en_US']").text();
else waitForElement(inputId + '_en_US', inputCurrent, inputId, xml);
var inputLabel = getInputLabel(inputId);
if (selectedLanguage == 'pt-PT') inputLabel.innerHTML = '';
else inputLabel.innerHTML = inputPT.value;
if (selectedLanguage == 'pt-PT') inputCurrent.value = inputPT.value;
else if (inputEN !== null) inputCurrent.value = inputEN.value;
else waitForElement(inputId + '_en_US', inputCurrent, inputId, xml);
}
function getSelectedLanguage(inputId) {
var languageContainer = document.getElementById('<portlet:namespace/>' + inputId + 'Menu');
return languageContainer.getElementsByClassName('btn-section')[0].innerHTML;
}
function getInputLabel(inputId) {
var boundingBoxContainer = document.getElementById(inputId + 'BoundingBox').parentElement;
return boundingBoxContainer.getElementsByClassName('form-text')[0];
}
function waitForElement(elementId, inputCurrent, inputId, xml) {
window.setTimeout(function() {
var element = document.getElementById(elementId);
if (element) elementCreated(element, inputCurrent, inputId, xml);
else waitForElement(elementId, inputCurrent, inputId, xml);
}, 500);
}
function elementCreated(inputEN, inputCurrent, inputId, xml) {
inputEN.value = $(xml).find("Title[language-id='en_US']").text();
var selectedLanguage = getSelectedLanguage(inputId);
if (selectedLanguage == 'en-US') inputCurrent.value = inputEN.value;
}
With this I am able to update the liferay-ui:input-localized inputs according to a pre-built XML String. I hope that someone finds this useful and if you have anything to add, please let me know!
To change the text value of an element, you must change the value of the elements's text node.
Example -
xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue = "new content"
Suppose "books.xml" is loaded into xmlDoc
Get the first child node of the element
Change the node value to "new content"

How can I add validation to an Input field? Binding JSON model doesn't work

I try to learn SAPUI5 with Samples frpm Demo kit Input - Checked. I get an error message: oInput.getBinding is not a function
I have a simple input field xml:
<Label text="Name" required="false" width="60%" visible="true"/>
<Input id="nameInput" type="Text" enabled="true" visible="true" valueHelpOnly="false" required="true" width="60%" valueStateText="Name must not be empty." maxLength="0" value="{previewModel>/name}" change= "onChange"/>
and my controller:
_validateInput: function(oInput) {
var oView = this.getView().byId("nameInput");
oView.setModel(this.getView().getModel("previewModel"));
var oBinding = oInput.getBinding("value");
var sValueState = "None";
var bValidationError = false;
try {
oBinding.getType().validateValue(oInput.getValue());
} catch (oException) {
sValueState = "Error";
bValidationError = true;
}
oInput.setValueState(sValueState);
return bValidationError;
},
/**
* Event handler for the continue button
*/
onContinue : function () {
// collect input controls
var that = this;
var oView = this.getView();
var aInputs =oView.byId("nameInput");
var bValidationError = false;
// check that inputs are not empty
// this does not happen during data binding as this is only triggered by changes
jQuery.each(aInputs, function (i, oInput) {
bValidationError = that._validateInput(oInput) || bValidationError;
});
// output result
if (!bValidationError) {
MessageToast.show("The input is validated. You could now continue to the next screen");
} else {
MessageBox.alert("A validation error has occured. Complete your input first");
}
},
// onChange update valueState of input
onChange: function(oEvent) {
var oInput = oEvent.getSource();
this._validateInput(oInput);
},
Can someone explain to me how I can set the Model?
Your model is fine and correctly binded.
The problem in your code is here, in the onContinue function
jQuery.each(aInputs, function (i, oInput) {
bValidationError = that._validateInput(oInput) || bValidationError;
});
aInput is not an array, so your code is not iterating on an array element.
To quickly fix this, you can put parentheses around the declaration like this:
var aInputs = [
oView.byId("nameInput")
];
Also, you could remove the first two lines of the _validateInput method since they are useless...
Usually, we set the model once the view is loaded, not when the value is changed. For example, if you would like to set a JSONModel with the name "previewModel", you can do as mentioned below.
Note that onInit is called when the controller is initialized. If you bind the model properly as follows, then the oEvent.getSource().getBinding("value") will return the expected value.
onInit: function(){
var oView = this.getView().byId("nameInput");
oView.setModel(new sap.ui.model.json.JSONModel({
name : "HELLO"
}), "previewModel");
},
onChange: function(oEvent) {
var oInput = oEvent.getSource();
this._validateInput(oInput);
},
...
Also, for validating the input text, you can do the following:
_validateInput: function(oInput) {
var oBinding = oInput.getBinding("value");
var sValueState = "None";
var sValueStateText = "";
var bValidationError = false;
if(oBinding.getValue().length === 0){
sValueState = "Error";
sValueStateText = "Custom Error"
}
oInput.setValueState(sValueState);
if(sValueState === "Error"){
oInput.setValueStateText(sValueStateText);
}
return bValidationError;
},
Please note that the code above is not high quality and production ready as it's a quick response to this post :)

Can't call jQuery function

I have a problem with my code.
I want to call a function but it's not working.
First, function show() displays button. This button has id='send' and it's inside the div with class='messagebox'. I want to call function on button click.
(I call function show in php script)
echo<<<ENDL
<div class="friendslistimgbox" onclick="show('$id','$login','$photo')">....</div>
ENDL;
$(.messagebox #send) or $(.messagebox > #send) are not working
$(document).ready(function(){
var conn = new WebSocket('ws://localhost:8080');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
console.log(e.data);
var data = JSON.parse(e.data);
var row = data.from+": "+data.msg+"<br/>";
$("#chats").append(row);
};
$(".messagebox #send").click(function(){
var userId = $("#userId").val();
var msg = $("#msg").val();
var data = {
userId: userId,
msg: msg
};
conn.send(JSON.stringify(data));
})
})
function show(id,login,photo){
$('.messagebox').html("<input type='hidden' id='userId' value='"+login+"'><input type='text' id='msg' class='sendmessage'><button id='send' type='submit' class='button_sendmessage'><i class='icon-right-dir'></i></button>");
$('#message_to').html("<a href='"+login+"'><img src='../userphotos/"+photo+"'>"+login+"</a>");
$("#allmessagesbox").css("visibility","visible");
}
HTML /
<div class="allmessagesbox" id="allmessagesbox">
<div class="messages">
<div class="message_to" id="message_to"></div>
</div>
<div class="messagebox"></div>
</div>
<div id="chats"></div>
You'll need to use the .on() method to register events with DOM elements that are dynamic (ie like your button, which might exist in the future).
In the case of your code, you can use on() in the following way:
// Replace this line:
// $(".messagebox #send").click(function(){
// With this:
$("body").on("click", ".messagebox #send", function(){
var userId = $("#userId").val();
var msg = $("#msg").val();
var data = {
userId: userId,
msg: msg
};
conn.send(JSON.stringify(data));
})
This can basically be read and understood as:
// For any dynamic element in scope or child of the body
$("body")
// Register a click event with any element that matches the
// .messagebox #send selector either now, or in the future
.on("click", ".messagebox #send", function(){
...
}));
For more information on on(), see the jQuery documentation

New Chat window

i've got a chat (without any design until now)
<div id="chatHtml">
<input type="text" id="input-text-chat" placeholder="Enter Text Chat">
<div id="chat-container">
<div id=chatOutput class="chat-output"></div>
</div>
</div>
Now I have a button, which calls ja javascript function to open a new window
<button type="button" v-on:click="openChat">open chat</button>
openChat: function() {
win = top.consoleRef = window.open('', 'myconsole',
'width=350,height=250' +
',menubar=0' +
',toolbar=1' +
',status=0' +
',scrollbars=1' +
',resizable=1')
chat = document.getElementById("chatHtml").innerHTML;
win.document.write(chat);
}
And last there is the code that the chat is working
document.getElementById('input-text-chat').onkeyup = function(e) {
if (e.keyCode != 13) return;
// removing trailing/leading whitespace
// this.value = this.value.replace(/^\s+|\s+$/g, '');
if (!this.value.length) return
connection.send(this.value);
console.log(connection.send);
console.log(this.value);
appendDIV(this.value);
this.value = '';
};
var chatContainer = document.querySelector('.chat-output');
function appendDIV(event) {
var div = document.createElement('div');
div.innerHTML = event.data || event;
chatContainer.insertBefore(div, chatContainer.firstChild);
div.tabIndex = 0;
div.focus();
document.getElementById('input-text-chat').focus();
win.document.write(chatContainer.innerHTML);
}
My Problem:
The chat is not working in the new window but on the "index window" it is.
Im completely new to javascript and i dont know whats the problem.
I thik its because of the ID's or sth.
Can sb help me, that i can use the chat in the new window?
Thanks :)
the input of your new page hasn't have event yet so bind it's event
just add this
openChat: function(){
win =top.consoleRef=window.open('','myconsole',
'width=350,height=250'
+',menubar=0'
+',toolbar=1'
+',status=0'
+',scrollbars=1'
+',resizable=1')
chat = document.getElementById("chatHtml").innerHTML;
win.document.write(chat);
win.document.getElementById('input-text-chat').onkeyup = function(e) {
if (e.keyCode != 13) return;
// removing trailing/leading whitespace
// this.value = this.value.replace(/^\s+|\s+$/g, '');
if (!this.value.length) return
connection.send(this.value);
console.log(connection.send);
console.log(this.value);
appendDIV(this.value);
this.value = '';
};
}
after
win.document.write(chatContainer.innerHTML);
also it's better if you put a name it that event to lessen your code

Categories

Resources