diff --git a/frontend-js/src/main/js/Functions.js b/frontend-js/src/main/js/Functions.js index 2a12658649d35c8f82b5c9b25b57d9af44108a60..2efead8718f9cc6db6173c2e79fbef5baf03fd7a 100644 --- a/frontend-js/src/main/js/Functions.js +++ b/frontend-js/src/main/js/Functions.js @@ -6,6 +6,8 @@ var Promise = require("bluebird"); var logger = require('./logger'); +var xss = require('xss'); + var Functions = {}; /** @@ -253,7 +255,15 @@ Functions.createElement = function (params) { result.type = params.inputType; } if (params.content !== null && params.content !== undefined) { - result.innerHTML = params.content; + if (params.xss !== false) { + var content = xss(params.content); + if (content !== params.content) { + logger.warn("XSS changed content: " + params.content); + } + result.innerHTML = content; + } else { + result.innerHTML = params.content; + } } if (params.style !== null && params.style !== undefined) { result.style.cssText = params.style; diff --git a/frontend-js/src/main/js/gui/Header.js b/frontend-js/src/main/js/gui/Header.js index d93dfccabe8c9b3d76ccf3c26c7f0fe251897ea5..65c76e1e2f71e0a18d650f0bd9935703262e059e 100644 --- a/frontend-js/src/main/js/gui/Header.js +++ b/frontend-js/src/main/js/gui/Header.js @@ -11,6 +11,7 @@ var OptionsMenu = require('./OptionsMenu'); var Promise = require("bluebird"); var logger = require('../logger'); +var xss = require('xss'); function Header(params) { AbstractGuiElement.call(this, params); @@ -35,7 +36,7 @@ Header.prototype._createHeaderGui = function (guiParams) { self.getElement().className = "minerva-header"; var projectId = self.getProject().getProjectId(); - var projectName = self.getProject().getName(); + var projectName = xss(self.getProject().getName()); var loadingDiv = Functions.createElement({ type: "div", @@ -55,7 +56,8 @@ Header.prototype._createHeaderGui = function (guiParams) { var link = Functions.createElement({ type: "a", style: "padding-right:15px; float:right", - content: '<i class="fa fa-lock" style="font-size:17px"></i> ' + content: '<i class="fa fa-lock" style="font-size:17px"></i> ', + xss: false }); link.href = ServerConnector.getServerBaseUrl() + "admin.xhtml?id=" + projectId; self.getElement().appendChild(link); @@ -84,7 +86,8 @@ Header.prototype._createHeaderGui = function (guiParams) { var bottom = top + link.outerHeight(); return self._optionsMenu.open(left, bottom, e.timeStamp); - } + }, + xss: false }); self.getElement().appendChild(menuLink); } @@ -93,7 +96,8 @@ Header.prototype._createHeaderGui = function (guiParams) { var homeLink = Functions.createElement({ type: "a", - content: '<i class="fa fa-home" style="font-size:17px"></i> ' + projectName + content: '<i class="fa fa-home" style="font-size:17px"></i> ' + projectName, + xss: false }); homeLink.href = ServerConnector.getServerBaseUrl() + "?id=" + projectId; self.getElement().appendChild(homeLink); diff --git a/frontend-js/src/main/js/gui/Legend.js b/frontend-js/src/main/js/gui/Legend.js index 6d584ea45e3686296bef6da7f6e670c185e5706c..6d499e1bff47d38473661604875c670d87aa8afa 100644 --- a/frontend-js/src/main/js/gui/Legend.js +++ b/frontend-js/src/main/js/gui/Legend.js @@ -18,60 +18,62 @@ function Legend(params) { Legend.prototype = Object.create(AbstractGuiElement.prototype); Legend.prototype.constructor = Legend; -Legend.prototype._initializeGui = function() { +Legend.prototype._initializeGui = function () { var self = this; var legendDiv = Functions.createElement({ - type : "div", - id : "legend-div", - className : "carousel slide", + type: "div", + id: "legend-div", + className: "carousel slide", }); self.getElement().appendChild(legendDiv); var indicators = Functions.createElement({ - type : "ol", - name : "indicators", - className : "carousel-indicators", + type: "ol", + name: "indicators", + className: "carousel-indicators", }); legendDiv.appendChild(indicators); self.setControlElement(PanelControlElementType.LEGEND_INDICATORS_OL, indicators); var slidesDiv = Functions.createElement({ - type : "div", - name : "slides", - className : "carousel-inner", - role : "listbox", + type: "div", + name: "slides", + className: "carousel-inner", + role: "listbox", }); legendDiv.appendChild(slidesDiv); self.setControlElement(PanelControlElementType.LEGEND_SLIDES_DIV, slidesDiv); var leftButton = Functions - .createElement({ - type : "a", - className : "left carousel-control", - role : "button", - href : "#legend-div", - content : '<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span><span class="sr-only">Previous</span>', - }); + .createElement({ + type: "a", + className: "left carousel-control", + role: "button", + href: "#legend-div", + content: '<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span><span class="sr-only">Previous</span>', + xss: false + }); leftButton.setAttribute("data-slide", "prev"); legendDiv.appendChild(leftButton); var rightButton = Functions - .createElement({ - type : "a", - className : "right carousel-control", - role : "button", - href : "#legend-div", - content : '<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span><span class="sr-only">Next</span>', - }); + .createElement({ + type: "a", + className: "right carousel-control", + role: "button", + href: "#legend-div", + content: '<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span><span class="sr-only">Next</span>', + xss: false + }); rightButton.setAttribute("data-slide", "next"); legendDiv.appendChild(rightButton); }; -Legend.prototype.hide = function() { +Legend.prototype.hide = function () { this.getElement().style.display = "none"; }; -Legend.prototype.show = function() { +Legend.prototype.show = function () { this.getElement().style.display = "block"; }; @@ -98,12 +100,12 @@ function createLegendSlide(file, index) { return result; } -Legend.prototype.init = function() { +Legend.prototype.init = function () { var self = this; var element = self.getElement(); var menu = self.getControlElement(PanelControlElementType.LEGEND_INDICATORS_OL); var slides = self.getControlElement(PanelControlElementType.LEGEND_SLIDES_DIV); - return ServerConnector.getConfigurationParam(ConfigurationType.LEGEND_FILES).then(function(legendFiles) { + return ServerConnector.getConfigurationParam(ConfigurationType.LEGEND_FILES).then(function (legendFiles) { for (var i = 0; i < legendFiles.length; i++) { var legendFile = legendFiles[i]; menu.appendChild(createLegendIndicator(legendFile, i)); diff --git a/frontend-js/src/main/js/gui/Panel.js b/frontend-js/src/main/js/gui/Panel.js index 4300b8c822b54650fc2287d0dc7b254478ef689d..814989486559ea3a64430e82e2f2bac2a08de77c 100644 --- a/frontend-js/src/main/js/gui/Panel.js +++ b/frontend-js/src/main/js/gui/Panel.js @@ -9,6 +9,7 @@ var PanelControlElementType = require('./PanelControlElementType'); var Functions = require('../Functions'); var logger = require('../logger'); +var xss = require('xss'); function Panel(params) { AbstractGuiElement.call(this, params); @@ -57,11 +58,12 @@ Panel.prototype.createHelpButton = function () { type: "button", className: "minerva-help-button", content: '<span class="ui-icon ui-icon-help" style="margin-left: -0.5em;"/>', + xss: false }); helpTipButton.onclick = function () { var helpDialogDiv = Functions.createElement({ type: "div", - content: self.getHelpTip(), + content: xss(self.getHelpTip()) }); $(helpDialogDiv).dialog({ close: function () { diff --git a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js index 96f23b449d4be7924c1a386fac1e7362880cd6e1..64679faba0f0d005725549c27637b2b8674edd21 100644 --- a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js @@ -1,8 +1,8 @@ "use strict"; -/* exported logger */ var Promise = require("bluebird"); var JSZip = require("jszip"); +var xss = require('xss'); var AbstractGuiElement = require('../AbstractGuiElement'); var ChooseAnnotatorsDialog = require('./ChooseAnnotatorsDialog'); @@ -12,6 +12,7 @@ var OverlayParser = require('../../map/OverlayParser'); var ZipEntry = require('./ZipEntry'); var Functions = require('../../Functions'); +// noinspection JSUnusedLocalSymbols var logger = require('../../logger'); var guiUtils = new (require('../leftPanel/GuiUtils'))(); @@ -228,7 +229,8 @@ AddProjectDialog.prototype.createGeneralTabContent = function () { return self.onSaveClicked().then(function () { return self.close(); }, GuiConnector.alert); - } + }, + xss: false }); var cancelButton = Functions.createElement({ type: "button", @@ -236,7 +238,8 @@ AddProjectDialog.prototype.createGeneralTabContent = function () { content: '<span class="ui-icon ui-icon-cancel"></span> CANCEL', onclick: function () { return self.close(); - } + }, + xss: false }); var menuRow = Functions.createElement({ type: "div", @@ -253,12 +256,13 @@ AddProjectDialog.prototype.createInputRow = function (labelName, defaultValue, i var label = new Functions.createElement({ type: "div", style: "display:table-cell", - content: labelName + content: xss(labelName) }); var input = new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='" + inputName + "' value='" + defaultValue + "'/>" + content: "<input name='" + xss(inputName) + "' value='" + xss(defaultValue) + "'/>", + xss: false }); return this.createRow([label, input]); }; @@ -267,7 +271,7 @@ AddProjectDialog.prototype.createCheckboxRow = function (labelName, defaultValue var label = new Functions.createElement({ type: "div", style: "display:table-cell", - content: labelName + content: xss(labelName) }); var checked = ""; if (defaultValue) { @@ -276,7 +280,8 @@ AddProjectDialog.prototype.createCheckboxRow = function (labelName, defaultValue var checkbox = new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input type='checkbox' name='" + inputName + "' " + checked + "/>" + content: "<input type='checkbox' name='" + xss(inputName) + "' " + checked + "/>", + xss: false }); var rowElements = [label, checkbox]; if (elements !== undefined) { @@ -854,7 +859,7 @@ AddProjectDialog.prototype.checkValidity = function () { isValid = false; } var projectId = self.getProjectId(); - if (!(/^[a-z0-9A-Z\-\_]+$/.test(projectId))){ + if (!(/^[a-z0-9A-Z\-\_]+$/.test(projectId))) { error += "<li>projectId can contain only alphanumeric characters and -_</li>"; isValid = false; } diff --git a/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js b/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js index d4109916dd2dfb595238eb873128b684fa561e22..74de218553b106023f0966c12ed825ce498cda81 100644 --- a/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js +++ b/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js @@ -30,13 +30,15 @@ ChooseAnnotatorsDialog.prototype.createGui = function () { content.appendChild(Functions.createElement({ type: "div", style: "display:table-cell", - content: "<div name='elementTree'/>" + content: "<div name='elementTree'/>", + xss: false })); content.appendChild(Functions.createElement({ type: "div", style: "display:table-cell", - content: "<div name='annotatorListBox'/>" + content: "<div name='annotatorListBox'/>", + xss: false })); self.getElement().appendChild(content); diff --git a/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js b/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js index 10b43ed57f4e88514e9d738120badaad008eeb51..2138412ac457978265fd9b309e9634548bb44d2e 100644 --- a/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js +++ b/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js @@ -30,13 +30,15 @@ ChooseValidatorsDialog.prototype.createGui = function () { content.appendChild(Functions.createElement({ type: "div", style: "display:table-cell", - content: "<div name='elementTree'/>" + content: "<div name='elementTree'/>", + xss: false })); content.appendChild(Functions.createElement({ type: "div", style: "display:table-cell", - content: "<div name='annotatorListBox'/>" + content: "<div name='annotatorListBox'/>", + xss: false })); self.getElement().appendChild(content); diff --git a/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js b/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js index 424b951e96625d123243b3dc780e8fd92dfe28dc..d17ed86cb05d633f18f20f25f0071a8457f93379 100644 --- a/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js +++ b/frontend-js/src/main/js/gui/admin/CommentsAdminPanel.js @@ -1,14 +1,13 @@ "use strict"; -/* exported Promise*/ -/* exported logger */ - var AbstractAdminPanel = require('./AbstractAdminPanel'); var Functions = require('../../Functions'); +// noinspection JSUnusedLocalSymbols var logger = require('../../logger'); var Promise = require("bluebird"); +var xss = require('xss'); function CommentsAdminPanel(params) { AbstractAdminPanel.call(this, params); @@ -22,19 +21,19 @@ CommentsAdminPanel.prototype.constructor = CommentsAdminPanel; CommentsAdminPanel.prototype._createGui = function () { var self = this; var projectsDiv = Functions.createElement({ - type: "div", + type: "div" }); self.getElement().appendChild(projectsDiv); var dataDiv = Functions.createElement({ type: "div", - style: "display:table", + style: "display:table" }); projectsDiv.appendChild(dataDiv); var commentsCell = Functions.createElement({ type: "div", - style: "display:table-cell;width:100%;vertical-align:top", + style: "display:table-cell;width:100%;vertical-align:top" }); projectsDiv.appendChild(commentsCell); @@ -42,37 +41,37 @@ CommentsAdminPanel.prototype._createGui = function () { type: "table", name: "commentsTable", className: "display", - style: "width:100%", + style: "width:100%" }); commentsCell.appendChild(commentsTable); $(commentsTable).DataTable({ columns: [{ - title: 'Id', + title: 'Id' }, { - title: 'Title', + title: 'Title' }, { - title: 'Author', + title: 'Author' }, { - title: 'Email', + title: 'Email' }, { - title: 'Content', + title: 'Content' }, { - title: 'Removed', + title: 'Removed' }, { - title: 'Pinned', - },], + title: 'Pinned' + }] }); var projectsCell = Functions.createElement({ type: "div", - style: "display:table-cell", + style: "display:table-cell" }); projectsDiv.appendChild(projectsCell); var selectProject = Functions.createElement({ type: "select", - name: "projectSelect", + name: "projectSelect" }); selectProject.size = "12"; selectProject.onchange = function () { @@ -81,7 +80,7 @@ CommentsAdminPanel.prototype._createGui = function () { projectsCell.appendChild(Functions.createElement({ type: "h3", - content: "Project", + content: "Project" })); projectsCell.appendChild(selectProject); }; @@ -195,10 +194,10 @@ CommentsAdminPanel.prototype.commentToTableRow = function (comment) { } var row = [comment.getId(), // - title, // - author, // - email, // - comment.getContent(), // + xss(title), // + xss(author), // + xss(email), // + xss(comment.getContent()), // remove, // toYesNo(comment.isPinned())]; return row; diff --git a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js index 9101aa76590a647c8042287d3d99e54f9cc96a80..06c5afaae85beb9f0b85b223fec08956bb1018a2 100644 --- a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js @@ -13,6 +13,7 @@ var Functions = require('../../Functions'); var logger = require('../../logger'); var guiUtils = new (require('../leftPanel/GuiUtils'))(); +var xss = require('xss'); function EditProjectDialog(params) { AbstractGuiElement.call(this, params); @@ -130,7 +131,8 @@ EditProjectDialog.prototype.createGeneralTabContent = function () { nameRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='projectName' value='" + project.getName() + "'/>" + content: "<input name='projectName' value='" + xss(project.getName()) + "'/>", + xss: false })); var versionRow = new Functions.createElement({ @@ -146,7 +148,8 @@ EditProjectDialog.prototype.createGeneralTabContent = function () { versionRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='projectVersion' value='" + project.getVersion() + "'/>" + content: "<input name='projectVersion' value='" + xss(project.getVersion()) + "'/>", + xss: false })); var diseaseRow = new Functions.createElement({ @@ -161,12 +164,13 @@ EditProjectDialog.prototype.createGeneralTabContent = function () { })); var disease = ""; if (project.getDisease() !== undefined) { - disease = project.getDisease().getResource(); + disease = xss(project.getDisease().getResource()); } diseaseRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='projectDisease' value='" + disease + "'/>" + content: "<input name='projectDisease' value='" + disease + "'/>", + xss: false })); var organismRow = new Functions.createElement({ @@ -181,12 +185,13 @@ EditProjectDialog.prototype.createGeneralTabContent = function () { })); var organism = ""; if (project.getOrganism() !== undefined) { - organism = project.getOrganism().getResource(); + organism = xss(project.getOrganism().getResource()); } organismRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='projectOrganism' value='" + organism + "'/>" + content: "<input name='projectOrganism' value='" + organism + "'/>", + xss: false })); var emailRow = new Functions.createElement({ @@ -201,12 +206,13 @@ EditProjectDialog.prototype.createGeneralTabContent = function () { })); var email = ""; if (project.getNotifyEmail() !== undefined) { - email = project.getNotifyEmail(); + email = xss(project.getNotifyEmail()); } emailRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='projectNotifyEmail' value='" + email + "'/>" + content: "<input name='projectNotifyEmail' value='" + email + "'/>", + xss: false })); var menuRow = Functions.createElement({ @@ -224,7 +230,8 @@ EditProjectDialog.prototype.createGeneralTabContent = function () { return self.onSaveClicked().then(function () { return self.close(); }, GuiConnector.alert); - } + }, + xss: false }); var cancelButton = Functions.createElement({ type: "button", @@ -232,7 +239,8 @@ EditProjectDialog.prototype.createGeneralTabContent = function () { content: '<span class="ui-icon ui-icon-cancel"></span> CANCEL', onclick: function () { return self.close(); - } + }, + xss: false }); menuRow.appendChild(saveProjectButton); menuRow.appendChild(cancelButton); diff --git a/frontend-js/src/main/js/gui/admin/EditUserDialog.js b/frontend-js/src/main/js/gui/admin/EditUserDialog.js index 930e1f250fcdf0db86c3291d0890d4eeb4860f18..aca5a8bc24e6cbfcc3fa356e4f8b256786ca717c 100644 --- a/frontend-js/src/main/js/gui/admin/EditUserDialog.js +++ b/frontend-js/src/main/js/gui/admin/EditUserDialog.js @@ -1,7 +1,7 @@ "use strict"; -/* exported logger */ var Promise = require("bluebird"); +var xss = require('xss'); var AbstractGuiElement = require('../AbstractGuiElement'); var GuiConnector = require('../../GuiConnector'); @@ -128,7 +128,7 @@ function getStringIfDefined(value) { if (value === undefined) { return ""; } - return value; + return xss(value); } EditUserDialog.prototype.createGeneralTabContent = function () { @@ -159,13 +159,15 @@ EditUserDialog.prototype.createGeneralTabContent = function () { loginRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='userLogin' value=''/>" + content: "<input name='userLogin' value=''/>", + xss: false })); } else { loginRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='userLogin' value='" + getStringIfDefined(user.getLogin()) + "' readonly/>" + content: "<input name='userLogin' value='" + getStringIfDefined(user.getLogin()) + "' readonly/>", + xss: false })); } @@ -182,7 +184,8 @@ EditUserDialog.prototype.createGeneralTabContent = function () { passwordRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input type=\"password\" name='userPassword' value=''/>" + content: "<input type=\"password\" name='userPassword' value=''/>", + xss: false })); var passwordRow2 = new Functions.createElement({ @@ -198,7 +201,8 @@ EditUserDialog.prototype.createGeneralTabContent = function () { passwordRow2.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input type=\"password\" name='userPassword2' value=''/>" + content: "<input type=\"password\" name='userPassword2' value=''/>", + xss: false })); var nameRow = new Functions.createElement({ @@ -214,7 +218,8 @@ EditUserDialog.prototype.createGeneralTabContent = function () { nameRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='userName' value='" + getStringIfDefined(user.getName()) + "'/>" + content: "<input name='userName' value='" + getStringIfDefined(user.getName()) + "'/>", + xss: false })); var surnameRow = new Functions.createElement({ @@ -230,7 +235,9 @@ EditUserDialog.prototype.createGeneralTabContent = function () { surnameRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='userSurname' value='" + getStringIfDefined(user.getSurname()) + "'/>" + content: "<input name='userSurname' value='" + getStringIfDefined(user.getSurname()) + "'/>", + xss: false + })); var emailRow = new Functions.createElement({ @@ -246,7 +253,8 @@ EditUserDialog.prototype.createGeneralTabContent = function () { emailRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='userEmail' value='" + getStringIfDefined(user.getEmail()) + "'/>" + content: "<input name='userEmail' value='" + getStringIfDefined(user.getEmail()) + "'/>", + xss: false })); @@ -265,7 +273,8 @@ EditUserDialog.prototype.createGeneralTabContent = function () { return self.onSaveClicked().then(function () { return self.close(); }, GuiConnector.alert); - } + }, + xss: false }); var cancelButton = Functions.createElement({ type: "button", @@ -273,7 +282,8 @@ EditUserDialog.prototype.createGeneralTabContent = function () { content: '<span class="ui-icon ui-icon-cancel"></span> CANCEL', onclick: function () { return self.close(); - } + }, + xss: false }); menuRow.appendChild(saveUserButton); menuRow.appendChild(cancelButton); diff --git a/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js b/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js index cbfb102bf861343188fd389ff6dbecbb73e983dc..b32f01eca3c92b0110a351ad728d3a061954ed7c 100644 --- a/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js +++ b/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js @@ -59,7 +59,8 @@ MapsAdminPanel.prototype._createMenuRow = function () { content: '<span class="ui-icon ui-icon-circle-plus"></span> ADD PROJECT', onclick: function () { return self.onAddClicked().then(null, GuiConnector.alert); - } + }, + xss: false }); var refreshButton = Functions.createElement({ type: "button", @@ -67,7 +68,8 @@ MapsAdminPanel.prototype._createMenuRow = function () { content: '<span class="ui-icon ui-icon-refresh"></span> REFRESH', onclick: function () { return self.onRefreshClicked().then(null, GuiConnector.alert); - } + }, + xss: false }); menuRow.appendChild(addProjectButton); menuRow.appendChild(refreshButton); diff --git a/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js b/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js index d03aeaa07b5933aff50d15de0d6495438bbd5c1a..5f018fb7fe2885afc05b318f7f97d31b7b07cb4e 100644 --- a/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js +++ b/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js @@ -1,5 +1,7 @@ "use strict"; +var Promise = require('bluebird'); + var AbstractAdminPanel = require('./AbstractAdminPanel'); var EditUserDialog = require('./EditUserDialog'); var User = require("../../map/data/User"); @@ -52,7 +54,8 @@ UsersAdminPanel.prototype._createMenuRow = function () { content: '<span class="ui-icon ui-icon-circle-plus"></span> ADD USER', onclick: function () { return self.onAddClicked().then(null, GuiConnector.alert); - } + }, + xss: false }); var refreshButton = Functions.createElement({ type: "button", @@ -60,7 +63,8 @@ UsersAdminPanel.prototype._createMenuRow = function () { content: '<span class="ui-icon ui-icon-refresh"></span> REFRESH', onclick: function () { return self.onRefreshClicked().then(null, GuiConnector.alert); - } + }, + xss: false }); menuRow.appendChild(addUserButton); menuRow.appendChild(refreshButton); diff --git a/frontend-js/src/main/js/gui/export/AbstractExportPanel.js b/frontend-js/src/main/js/gui/export/AbstractExportPanel.js index f053c242370a12d0cd496aa3b40c9690915021af..144896dd3345c6be727393ffe219244994255579 100644 --- a/frontend-js/src/main/js/gui/export/AbstractExportPanel.js +++ b/frontend-js/src/main/js/gui/export/AbstractExportPanel.js @@ -118,14 +118,16 @@ AbstractExportPanel.prototype._createSelectTypeDiv = function (elementTypes) { processedNames[name] = true; var row = Functions.createElement({ type: "li", - content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"" + name + "\" value=\"" + name + "\" />" + name + "</label></div>" + content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"" + name + "\" value=\"" + name + "\" />" + name + "</label></div>", + xss: false }); choicesContainer.appendChild(row); } } choicesContainer.appendChild(Functions.createElement({ type: "li", - content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"ALL\" value=\"ALL\" />ALL</label></div>" + content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"ALL\" value=\"ALL\" />ALL</label></div>", + xss: false })); return typeDiv; }; @@ -178,13 +180,15 @@ AbstractExportPanel.prototype._createSelectColumnDiv = function (columnTypes) { var row = Functions.createElement({ type: "li", content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"column_" + columnType.columnName - + "\" value=\"" + columnType.columnName + "\" />" + columnType.name + "</label></div>" + + "\" value=\"" + columnType.columnName + "\" />" + columnType.name + "</label></div>", + xss: false }); choicesContainer.appendChild(row); } choicesContainer.appendChild(Functions.createElement({ type: "li", - content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"ALL\" value=\"ALL\" />ALL</label></div>" + content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"ALL\" value=\"ALL\" />ALL</label></div>", + xss: false })); return columnDiv; }; diff --git a/frontend-js/src/main/js/gui/export/GraphicsExportPanel.js b/frontend-js/src/main/js/gui/export/GraphicsExportPanel.js index 21b5445168cca96c0ffd4688958f541c7457763a..379f0e930ccb9ffb6041cc9e1a5f7821de84eee5 100644 --- a/frontend-js/src/main/js/gui/export/GraphicsExportPanel.js +++ b/frontend-js/src/main/js/gui/export/GraphicsExportPanel.js @@ -7,6 +7,7 @@ var Functions = require('../../Functions'); var GuiConnector = require('../../GuiConnector'); var logger = require('../../logger'); +var xss = require('xss'); function GraphicsExportPanel(params) { params.panelName = "graphicsExport"; @@ -16,33 +17,33 @@ function GraphicsExportPanel(params) { GraphicsExportPanel.prototype = Object.create(AbstractExportPanel.prototype); GraphicsExportPanel.prototype.constructor = GraphicsExportPanel; -GraphicsExportPanel.prototype.init = function() { +GraphicsExportPanel.prototype.init = function () { var self = this; var element = self.getElement(); var configuration; element.appendChild(self._createSelectProjectDiv()); - return ServerConnector.getConfiguration().then(function(result) { + return ServerConnector.getConfiguration().then(function (result) { configuration = result; element.appendChild(self._createSelectGraphicsFormatDiv(configuration.getImageConverters())); element.appendChild(self._createDownloadButton()); - }).then(function() { + }).then(function () { $(window).trigger('resize'); }); }; -GraphicsExportPanel.prototype._createSelectProjectDiv = function() { +GraphicsExportPanel.prototype._createSelectProjectDiv = function () { var self = this; var typeDiv = Functions.createElement({ - type : "div", - name : "modelSelectDiv", + type: "div", + name: "modelSelectDiv" }); typeDiv.appendChild(Functions.createElement({ - type : "h4", - content : "(Sub)map:", + type: "h4", + content: "(Sub)map:" })); var choicesContainer = Functions.createElement({ - type : "ul", + type: "ul" }); typeDiv.appendChild(choicesContainer); @@ -54,10 +55,12 @@ GraphicsExportPanel.prototype._createSelectProjectDiv = function() { if (i === 0) { checkedString = ' checked="checked" '; } + var modelName = xss(model.getName()); var row = Functions.createElement({ - type : "li", - content : '<div><label> <input type="radio" name="model" value="' + model.getId() + '"' + checkedString + '/>' - + model.getName() + '</label></div>', + type: "li", + content: '<div><label> <input type="radio" name="model" value="' + model.getId() + '"' + checkedString + '/>' + + modelName + '</label></div>', + xss: false }); choicesContainer.appendChild(row); } @@ -65,18 +68,18 @@ GraphicsExportPanel.prototype._createSelectProjectDiv = function() { return typeDiv; }; -GraphicsExportPanel.prototype._createSelectGraphicsFormatDiv = function(formats) { +GraphicsExportPanel.prototype._createSelectGraphicsFormatDiv = function (formats) { var typeDiv = Functions.createElement({ - type : "div", - name : "formatSelectDiv", + type: "div", + name: "formatSelectDiv", }); typeDiv.appendChild(Functions.createElement({ - type : "h4", - content : "Format:", + type: "h4", + content: "Format:", })); var choicesContainer = Functions.createElement({ - type : "ul", + type: "ul", }); typeDiv.appendChild(choicesContainer); @@ -87,9 +90,11 @@ GraphicsExportPanel.prototype._createSelectGraphicsFormatDiv = function(formats) checkedString = ' checked="checked" '; } var row = Functions.createElement({ - type : "li", - content : '<div><label> <input type="radio" name="format" value="' + format.handler + '"' + checkedString + '/>' - + format.name + '</label></div>', + type: "li", + content: '<div><label> <input type="radio" name="format" value="' + format.handler + '"' + checkedString + '/>' + + format.name + '</label></div>', + xss: false + }); choicesContainer.appendChild(row); } @@ -97,37 +102,37 @@ GraphicsExportPanel.prototype._createSelectGraphicsFormatDiv = function(formats) return typeDiv; }; -GraphicsExportPanel.prototype.getSubmapId = function() { +GraphicsExportPanel.prototype.getSubmapId = function () { var self = this; var div = $("div[name='modelSelectDiv']", $(self.getElement()))[0]; var id = null; - $(":checked", $(div)).each(function(index, element) { + $(":checked", $(div)).each(function (index, element) { id = element.value; }); return id; }; -GraphicsExportPanel.prototype.getFormatHandler = function() { +GraphicsExportPanel.prototype.getFormatHandler = function () { var self = this; var div = $("div[name='formatSelectDiv']", $(self.getElement()))[0]; var format = null; - $(":checked", $(div)).each(function(index, element) { + $(":checked", $(div)).each(function (index, element) { format = element.value; }); return format; }; -GraphicsExportPanel.prototype._createDownloadButton = function() { +GraphicsExportPanel.prototype._createDownloadButton = function () { var self = this; var downloadDiv = Functions.createElement({ - type : "div", - name : "downloadDiv", - style : "clear:both; padding: 10px;", + type: "div", + name: "downloadDiv", + style: "clear:both; padding: 10px;", }); var button = Functions.createElement({ - type : "button", - name : "downloadButton", - content : " Download", - onclick : function() { + type: "button", + name: "downloadButton", + content: " Download", + onclick: function () { var identifier = null; var defaultOverlayName = "Network"; for (var i = 0; i < self.getProject().getModel().getLayouts().length; i++) { @@ -138,10 +143,10 @@ GraphicsExportPanel.prototype._createDownloadButton = function() { } return ServerConnector.getImageDownloadUrl({ - modelId : self.getSubmapId(), - backgroundOverlayId : identifier, - handlerClass : self.getFormatHandler(), - }).then(function(url) { + modelId: self.getSubmapId(), + backgroundOverlayId: identifier, + handlerClass: self.getFormatHandler(), + }).then(function (url) { return self.downloadFile(url); }).then(null, GuiConnector.alert); }, diff --git a/frontend-js/src/main/js/gui/leftPanel/AbstractDbPanel.js b/frontend-js/src/main/js/gui/leftPanel/AbstractDbPanel.js index a73bc3a727fbb7ca63399fa1b5b5fde5cbd684ab..4ac01269f335e0baedb92c2ea2a709028e9c19b6 100644 --- a/frontend-js/src/main/js/gui/leftPanel/AbstractDbPanel.js +++ b/frontend-js/src/main/js/gui/leftPanel/AbstractDbPanel.js @@ -128,7 +128,8 @@ AbstractPanel.prototype._initializeGui = function (placeholder) { var searchButton = Functions.createElement({ type: "a", - content: '<img src="resources/images/icons/search.png"/>' + content: '<img src="resources/images/icons/search.png"/>', + xss: false }); searchButton.href = "#"; searchButtonCell.appendChild(searchButton); @@ -145,7 +146,8 @@ AbstractPanel.prototype._initializeGui = function (placeholder) { var searchResultsNavTabDiv = Functions.createElement({ type: "ul", className: "nav nav-tabs", - content: '<li class="active"><a href="#set1"/></li>' + content: '<li class="active"><a href="#set1"/></li>', + xss: false }); searchResultsDiv.appendChild(searchResultsNavTabDiv); this.setControlElement(PanelControlElementType.SEARCH_RESULTS_NAV_TAB, searchResultsNavTabDiv); @@ -153,7 +155,8 @@ AbstractPanel.prototype._initializeGui = function (placeholder) { var searchResultsContentTabDiv = Functions.createElement({ type: "div", className: "tab-content", - content: '<div class="tab-pane fade active in" name="set1" id="set1"/>' + content: '<div class="tab-pane fade active in" name="set1" id="set1"/>', + xss: false }); searchResultsDiv.appendChild(searchResultsContentTabDiv); this.setControlElement(PanelControlElementType.SEARCH_RESULTS_CONTENT_TAB, searchResultsContentTabDiv); diff --git a/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js b/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js index 6fe0618af056e67830c0372726c6f578add060fd..110085be7290cf541c26f81742eb2f56c99294a7 100644 --- a/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js +++ b/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js @@ -151,8 +151,7 @@ OverlayPanel.prototype.createOverlayRow = function (overlay, checked) { result.className = "active"; } - var nameTd = document.createElement("td"); - nameTd.innerHTML = overlay.getName(); + var nameTd = Functions.createElement({type: "td", content: overlay.getName(), xss: true}); result.appendChild(nameTd); var viewTd = document.createElement("td"); diff --git a/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js b/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js index 80afa012a6ceb798e70934e08ed8ef660c27b487..cba0dd4719ed8e5737ff7347aa99eaf97ffb5033 100644 --- a/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js +++ b/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js @@ -111,24 +111,25 @@ ProjectInfoPanel.prototype._createInfoPanelGui = function () { var projectPublicationsButton = Functions.createElement({ type: "a", - name: "projectPublicationsButton", + name: "projectPublicationsButton" }); projectPublicationsButton.appendChild(Functions.createElement({ type: "span", content: "<i class='fa fa-list'> ", + xss: false })); projectPublicationsButton.appendChild(projectPublicationsText); projectPublicationsButton.appendChild(Functions.createElement({ type: "span", style: "font-family:FontAwesome; font-weight: normal;font-style: normal;cursor: pointer", - content: " publication(s)", + content: " publication(s)" })); this.setControlElement(PanelControlElementType.INFO_PROJECT_SHOW_PUBLICATIONS_BUTTON, projectPublicationsButton); var liElement = Functions.createElement({ type: "li", - style: "line-height: 30px;", + style: "line-height: 30px;" }); liElement.appendChild(projectPublicationsButton); dataTab.appendChild(liElement); @@ -138,11 +139,12 @@ ProjectInfoPanel.prototype._createInfoPanelGui = function () { name: "projectOriginalFileButton", href: "#", content: "<i class='fa fa-files-o'> source file", + xss: false }); this.setControlElement(PanelControlElementType.INFO_PROJECT_GET_ORIGINAL_FILE_BUTTON, projectOriginalFileButton); liElement = Functions.createElement({ type: "li", - style: "line-height: 30px", + style: "line-height: 30px" }); liElement.appendChild(projectOriginalFileButton); dataTab.appendChild(liElement); @@ -156,11 +158,12 @@ ProjectInfoPanel.prototype._createInfoPanelGui = function () { if (ServerConnector.getSessionData().getToken() === undefined) { exportButton.href = ServerConnector.getServerBaseUrl() + "login.xhtml?from=" + encodeURI(exportButton.href); } - } + }, + xss: false }); liElement = Functions.createElement({ type: "li", - style: "line-height: 30px", + style: "line-height: 30px" }); liElement.appendChild(exportButton); dataTab.appendChild(liElement); @@ -169,6 +172,7 @@ ProjectInfoPanel.prototype._createInfoPanelGui = function () { type: "a", name: "manualLink", content: '<i class="fa fa-file"> MANUAL', + xss: false }); manualButton.href = "#"; manualButton.onclick = function () { @@ -179,7 +183,7 @@ ProjectInfoPanel.prototype._createInfoPanelGui = function () { }; liElement = Functions.createElement({ type: "li", - style: "line-height: 30px", + style: "line-height: 30px" }); liElement.appendChild(manualButton); dataTab.appendChild(liElement); @@ -244,7 +248,8 @@ ProjectInfoPanel.prototype._createUserDataTab = function () { var userDataTitle = Functions.createElement({ type: "h3", - content: '<img src="./resources/images/profile.png" border="0" align="left"/><br/>User data<br/>' + content: '<img src="./resources/images/profile.png" border="0" align="left"/><br/>User data<br/>', + xss: false }); userDataDiv.appendChild(userDataTitle); @@ -324,6 +329,8 @@ ProjectInfoPanel.prototype._createUserDataTab = function () { content: '<h3><img src="./resources/images/profile.png" border="0" align="left"/>' + '<br/>User data</h3><br/>YOU ARE NOT LOGGED IN.<br/>' + '<center><button>LOGIN</button></center>' + '<br/><a hreg="#" name="requestAccount">Request an account</a>', + xss: false + }); $(loginTabDiv).find("button")[0].onclick = function () { return self.getParent().getLoginDialog().open(); diff --git a/frontend-js/src/main/js/gui/topMenu/TopMenu.js b/frontend-js/src/main/js/gui/topMenu/TopMenu.js index d498e1a9b1e4d73f737a4a9438c9deba9674291d..a639680d4874b7843b5d3255573feca1babae7be 100644 --- a/frontend-js/src/main/js/gui/topMenu/TopMenu.js +++ b/frontend-js/src/main/js/gui/topMenu/TopMenu.js @@ -64,7 +64,7 @@ TopMenu.prototype._createGui = function () { var showOverviewDiv = Functions.createElement({ type: "div", - style: "float: left;", + style: "float: left;" }); self.getElement().appendChild(showOverviewDiv); @@ -74,46 +74,47 @@ TopMenu.prototype._createGui = function () { name: "showOverviewButton", content: "<i class='fa fa-sitemap' style='font-size:18px; font-weight:400; padding-right:10px;'></i><span >SHOW OVERVIEW</span>", style: "display:none", + xss: false }); showOverviewDiv.appendChild(showOverviewButton); self.setControlElement(PanelControlElementType.MENU_SHOW_OVERVIEW_BUTTON, showOverviewButton); var rightHeaderMenuDiv = Functions.createElement({ type: "div", - className: "rightHeaderMenu", + className: "rightHeaderMenu" }); self.getElement().appendChild(rightHeaderMenuDiv); var div4checkboxes = Functions.createElement({ type: "div", - className: "minerva-top-checkbox-div", + className: "minerva-top-checkbox-div" }); rightHeaderMenuDiv.appendChild(div4checkboxes); var legendCheckbox = Functions.createElement({ type: "input", inputType: "checkbox", - name: "legendCheckbox", + name: "legendCheckbox" }); div4checkboxes.appendChild(legendCheckbox); self.setControlElement(PanelControlElementType.MENU_LEGEND_CHECKBOX, legendCheckbox); div4checkboxes.appendChild(Functions.createElement({ type: "label", - content: "LEGEND", + content: "LEGEND" })); var commentCheckbox = Functions.createElement({ type: "input", inputType: "checkbox", - name: "commentCheckbox", + name: "commentCheckbox" }); div4checkboxes.appendChild(commentCheckbox); self.setControlElement(PanelControlElementType.MENU_COMMENTS_CHECKBOX, commentCheckbox); div4checkboxes.appendChild(Functions.createElement({ type: "label", - content: "COMMENTS", + content: "COMMENTS" })); var refreshCommentButton = Functions.createElement({ @@ -122,6 +123,7 @@ TopMenu.prototype._createGui = function () { name: "refreshCommentButton", content: "<i class='fa fa-refresh' style='font-size:21px; font-weight:400;'></i>", style: "display:none", + xss: false }); div4checkboxes.appendChild(refreshCommentButton); self.setControlElement(PanelControlElementType.MENU_REFRESH_COMMENTS_BUTTON, refreshCommentButton); @@ -131,6 +133,7 @@ TopMenu.prototype._createGui = function () { className: "minerva-overview-button", name: "clearButton", content: "<i class='fa fa-times' style='font-size:18px; font-weight:300; padding-right:10px;'></i>CLEAR", + xss: false }); rightHeaderMenuDiv.appendChild(clearButton); self.setControlElement(PanelControlElementType.MENU_CLEAR_BUTTON, clearButton); diff --git a/frontend-js/src/main/js/map/window/AbstractInfoWindow.js b/frontend-js/src/main/js/map/window/AbstractInfoWindow.js index 6717333765576efca38ec0ddd8ced1f24cc390d1..60f98814f24ad90fe108bdd0dfa45602611e109a 100644 --- a/frontend-js/src/main/js/map/window/AbstractInfoWindow.js +++ b/frontend-js/src/main/js/map/window/AbstractInfoWindow.js @@ -1,7 +1,6 @@ "use strict"; var Promise = require("bluebird"); -var xss = require("xss"); var logger = require('../../logger'); var Functions = require('../../Functions'); @@ -262,8 +261,7 @@ AbstractInfoWindow.prototype._createCommentInfoDiv = function (overlay, data) { commentId.innerHTML = '#' + comment.getId(); result.appendChild(commentId); result.appendChild(document.createElement("br")); - var commentContent = document.createElement("div"); - commentContent.innerHTML = xss(comment.getContent()); + var commentContent = Functions.createElement({type: "div", content: comment.getContent(), xss: true}); result.appendChild(commentContent); }