mirror of https://github.com/portainer/portainer
feat(app): fix XSS vulnerabilities (#3230)
parent
2912e78f68
commit
b0f48ee3ad
|
@ -1,4 +1,5 @@
|
|||
import '../assets/css/app.css';
|
||||
import './libraries/isteven-angular-multiselect/isteven-multi-select.css';
|
||||
import angular from 'angular';
|
||||
|
||||
import './agent/_module';
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
.git
|
||||
.gitignore
|
||||
bower.json
|
||||
CHANGELOG.md
|
||||
package.json
|
||||
README.md
|
||||
screenshot.png
|
||||
/doc
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015 Ignatius Steven (https://github.com/isteven)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,50 @@
|
|||
# AngularJS MultiSelect
|
||||
Pure AngularJS directive which creates a dropdown button with multiple or single selections.
|
||||
Doesn't require jQuery and works well with other Javascript libraries.
|
||||
|
||||
![Screenshot](https://raw.githubusercontent.com/isteven/angular-multi-select/master/screenshot.png)
|
||||
|
||||
### Demo & How To
|
||||
Go to http://isteven.github.io/angular-multi-select
|
||||
|
||||
### Current Version
|
||||
4.0.0
|
||||
|
||||
### Change Log
|
||||
See <a href="https://github.com/isteven/angular-multi-select/blob/master/CHANGELOG.md">CHANGELOG.md</a>.
|
||||
For those who's upgrading from version 2.x.x, do note that this version is not backward-compatible. Please read the manual
|
||||
thoroughly and update your code accordingly.
|
||||
|
||||
### Bug Reporting
|
||||
Please follow these steps:
|
||||
|
||||
1. **READ THE MANUAL AGAIN**. You might have missed something. This includes the MINIMUM ANGULARJS VERSION and the SUPPORTED BROWSERS.
|
||||
2. The next step is to search in Github's issue section first. There might already be an answer for similar issue. Do check both open and closed issues.
|
||||
3. If there's no previous issue found, then please create a new issue in https://github.com/isteven/angular-multi-select/issues.
|
||||
4. Please **replicate the problem in JSFiddle or Plunker** (or any other online JS collaboration tool), and include the URL in the issue you are creating.
|
||||
5. When you're done, please close the issue you've created.
|
||||
|
||||
### Licence
|
||||
Released under the MIT license:
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015 Ignatius Steven (https://github.com/isteven)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* Don't modify things marked with ! - unless you know what you're doing
|
||||
*/
|
||||
|
||||
/* ! vertical layout */
|
||||
.multiSelect .vertical {
|
||||
float: none;
|
||||
}
|
||||
|
||||
/* ! horizontal layout */
|
||||
.multiSelect .horizontal:not(.multiSelectGroup) {
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* ! create a "row" */
|
||||
.multiSelect .line {
|
||||
padding: 2px 0px 4px 0px;
|
||||
max-height: 30px;
|
||||
overflow: hidden;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
/* ! create a "column" */
|
||||
.multiSelect .acol {
|
||||
display: inline-block;
|
||||
min-width: 12px;
|
||||
}
|
||||
|
||||
/* ! */
|
||||
.multiSelect .inlineBlock {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* the multiselect button */
|
||||
.multiSelect > button {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border: 1px solid #c6c6c6;
|
||||
padding: 1px 8px 1px 8px;
|
||||
font-size: 14px;
|
||||
min-height : 38px !important;
|
||||
border-radius: 4px;
|
||||
color: #555;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
white-space:normal;
|
||||
background-color: #fff;
|
||||
background-image: linear-gradient(#fff, #f7f7f7);
|
||||
}
|
||||
|
||||
/* button: hover */
|
||||
.multiSelect > button:hover {
|
||||
background-image: linear-gradient(#fff, #e9e9e9);
|
||||
}
|
||||
|
||||
/* button: disabled */
|
||||
.multiSelect > button:disabled {
|
||||
background-image: linear-gradient(#fff, #fff);
|
||||
border: 1px solid #ddd;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* button: clicked */
|
||||
.multiSelect .buttonClicked {
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15) inset, 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
/* labels on the button */
|
||||
.multiSelect .buttonLabel {
|
||||
display: inline-block;
|
||||
padding: 5px 0px 5px 0px;
|
||||
}
|
||||
|
||||
/* downward pointing arrow */
|
||||
.multiSelect .caret {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin: 0px 0px 1px 12px !important;
|
||||
vertical-align: middle;
|
||||
border-top: 4px solid #333;
|
||||
border-right: 4px solid transparent;
|
||||
border-left: 4px solid transparent;
|
||||
border-bottom: 0 dotted;
|
||||
}
|
||||
|
||||
/* the main checkboxes and helper layer */
|
||||
.multiSelect .checkboxLayer {
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
border: 1px solid rgba(0, 0, 0, 0.15);
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||
min-width:278px;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* container of helper elements */
|
||||
.multiSelect .helperContainer {
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 8px 8px 0px 8px;
|
||||
}
|
||||
|
||||
/* helper buttons (select all, none, reset); */
|
||||
.multiSelect .helperButton {
|
||||
display: inline;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border: 1px solid #ccc;
|
||||
height: 26px;
|
||||
font-size: 13px;
|
||||
border-radius: 2px;
|
||||
color: #666;
|
||||
background-color: #f1f1f1;
|
||||
line-height: 1.6;
|
||||
margin: 0px 0px 8px 0px;
|
||||
}
|
||||
|
||||
.multiSelect .helperButton.reset{
|
||||
float: right;
|
||||
}
|
||||
|
||||
.multiSelect .helperButton:not( .reset ) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
/* clear button */
|
||||
.multiSelect .clearButton {
|
||||
position: absolute;
|
||||
display: inline;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border: 1px solid #ccc;
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
font-size: 13px;
|
||||
border-radius: 2px;
|
||||
color: #666;
|
||||
background-color: #f1f1f1;
|
||||
line-height: 1.4;
|
||||
right : 2px;
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
/* filter */
|
||||
.multiSelect .inputFilter {
|
||||
border-radius: 2px;
|
||||
border: 1px solid #ccc;
|
||||
height: 26px;
|
||||
font-size: 14px;
|
||||
width:100%;
|
||||
padding-left:7px;
|
||||
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
|
||||
-moz-box-sizing: border-box; /* Firefox, other Gecko */
|
||||
box-sizing: border-box; /* Opera/IE 8+ */
|
||||
color: #888;
|
||||
margin: 0px 0px 8px 0px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
}
|
||||
|
||||
/* helper elements on hover & focus */
|
||||
.multiSelect .clearButton:hover,
|
||||
.multiSelect .helperButton:hover {
|
||||
border: 1px solid #ccc;
|
||||
color: #999;
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.multiSelect .helperButton:disabled {
|
||||
color: #ccc;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.multiSelect .clearButton:focus,
|
||||
.multiSelect .helperButton:focus,
|
||||
.multiSelect .inputFilter:focus {
|
||||
border: 1px solid #66AFE9 !important;
|
||||
outline: 0;
|
||||
-webkit-box-shadow: inset 0 0 1px rgba(0,0,0,.065), 0 0 5px rgba(102, 175, 233, .6) !important;
|
||||
box-shadow: inset 0 0 1px rgba(0,0,0,.065), 0 0 5px rgba(102, 175, 233, .6) !important;
|
||||
}
|
||||
|
||||
/* container of multi select items */
|
||||
.multiSelect .checkBoxContainer {
|
||||
display: block;
|
||||
padding: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ! to show / hide the checkbox layer above */
|
||||
.multiSelect .show {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* item labels */
|
||||
.multiSelect .multiSelectItem {
|
||||
display: block;
|
||||
padding: 3px;
|
||||
color: #444;
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
border: 1px solid transparent;
|
||||
position: relative;
|
||||
min-width:278px;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
/* Styling on selected items */
|
||||
.multiSelect .multiSelectItem:not(.multiSelectGroup).selected
|
||||
{
|
||||
background-image: linear-gradient( #e9e9e9, #f1f1f1 );
|
||||
color: #555;
|
||||
cursor: pointer;
|
||||
border-top: 1px solid #e4e4e4;
|
||||
border-left: 1px solid #e4e4e4;
|
||||
border-right: 1px solid #d9d9d9;
|
||||
}
|
||||
|
||||
.multiSelect .multiSelectItem .acol label {
|
||||
display: inline-block;
|
||||
padding-right: 30px;
|
||||
margin: 0px;
|
||||
font-weight: normal;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/* item labels focus on mouse hover */
|
||||
.multiSelect .multiSelectItem:hover,
|
||||
.multiSelect .multiSelectGroup:hover {
|
||||
background-image: linear-gradient( #c1c1c1, #999 ) !important;
|
||||
color: #fff !important;
|
||||
cursor: pointer;
|
||||
border: 1px solid #ccc !important;
|
||||
}
|
||||
|
||||
/* item labels focus using keyboard */
|
||||
.multiSelect .multiSelectFocus {
|
||||
background-image: linear-gradient( #c1c1c1, #999 ) !important;
|
||||
color: #fff !important;
|
||||
cursor: pointer;
|
||||
border: 1px solid #ccc !important;
|
||||
}
|
||||
|
||||
/* change mouse pointer into the pointing finger */
|
||||
.multiSelect .multiSelectItem span:hover,
|
||||
.multiSelect .multiSelectGroup span:hover
|
||||
{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ! group labels */
|
||||
.multiSelect .multiSelectGroup {
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* right-align the tick mark (✔) */
|
||||
.multiSelect .tickMark {
|
||||
display:inline-block;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 7px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
/* hide the original HTML checkbox away */
|
||||
.multiSelect .checkbox {
|
||||
color: #ddd !important;
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* checkboxes currently disabled */
|
||||
.multiSelect .disabled,
|
||||
.multiSelect .disabled:hover,
|
||||
.multiSelect .disabled label input:hover ~ span {
|
||||
color: #c4c4c4 !important;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
/* If you use images in button / checkbox label, you might want to change the image style here. */
|
||||
.multiSelect img {
|
||||
vertical-align: middle;
|
||||
margin-bottom:0px;
|
||||
max-height: 22px;
|
||||
max-width:22px;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "isteven-angular-multiselect",
|
||||
"version": "v4.0.0",
|
||||
"description": "A multi select dropdown directive for AngularJS",
|
||||
"main": [
|
||||
"isteven-multi-select.js",
|
||||
"isteven-multi-select.css"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/isteven/angular-multi-select.git"
|
||||
},
|
||||
"keywords": [
|
||||
"angular"
|
||||
],
|
||||
"author": "Ignatius Steven <isteven.github@gmail.com> (https://github.com/isteven)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/isteven/angular-multi-select/issues"
|
||||
},
|
||||
"homepage": "https://github.com/isteven/angular-multi-select"
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import bootbox from 'bootbox';
|
||||
|
||||
angular.module('portainer.app')
|
||||
.factory('ModalService', [function ModalServiceFactory() {
|
||||
.factory('ModalService', [ '$sanitize', function ModalServiceFactory($sanitize) {
|
||||
'use strict';
|
||||
var service = {};
|
||||
|
||||
|
@ -17,17 +17,18 @@ angular.module('portainer.app')
|
|||
var confirmButtons = function(options) {
|
||||
var buttons = {
|
||||
confirm: {
|
||||
label: options.buttons.confirm.label,
|
||||
className: options.buttons.confirm.className
|
||||
label: $sanitize(options.buttons.confirm.label),
|
||||
className: $sanitize(options.buttons.confirm.className)
|
||||
},
|
||||
cancel: {
|
||||
label: options.buttons.cancel && options.buttons.cancel.label ? options.buttons.cancel.label : 'Cancel'
|
||||
label: options.buttons.cancel && options.buttons.cancel.label ? $sanitize(options.buttons.cancel.label) : 'Cancel'
|
||||
}
|
||||
};
|
||||
return buttons;
|
||||
};
|
||||
|
||||
service.enlargeImage = function(image) {
|
||||
image = $sanitize(image);
|
||||
bootbox.dialog({
|
||||
message: '<img src="' + image + '" style="width:100%" />',
|
||||
className: 'image-zoom-modal',
|
||||
|
@ -45,7 +46,7 @@ angular.module('portainer.app')
|
|||
applyBoxCSS(box);
|
||||
};
|
||||
|
||||
service.prompt = function(options){
|
||||
function prompt(options){
|
||||
var box = bootbox.prompt({
|
||||
title: options.title,
|
||||
inputType: options.inputType,
|
||||
|
@ -54,9 +55,9 @@ angular.module('portainer.app')
|
|||
callback: options.callback
|
||||
});
|
||||
applyBoxCSS(box);
|
||||
};
|
||||
}
|
||||
|
||||
service.customPrompt = function(options, optionToggled) {
|
||||
function customPrompt(options, optionToggled) {
|
||||
var box = bootbox.prompt({
|
||||
title: options.title,
|
||||
inputType: options.inputType,
|
||||
|
@ -67,7 +68,7 @@ angular.module('portainer.app')
|
|||
applyBoxCSS(box);
|
||||
box.find('.bootbox-body').prepend('<p>' + options.message + '</p>');
|
||||
box.find('.bootbox-input-checkbox').prop('checked', optionToggled);
|
||||
};
|
||||
}
|
||||
|
||||
service.confirmAccessControlUpdate = function(callback) {
|
||||
service.confirm({
|
||||
|
@ -98,6 +99,7 @@ angular.module('portainer.app')
|
|||
};
|
||||
|
||||
service.confirmDeletion = function(message, callback) {
|
||||
message = $sanitize(message);
|
||||
service.confirm({
|
||||
title: 'Are you sure ?',
|
||||
message: message,
|
||||
|
@ -112,7 +114,7 @@ angular.module('portainer.app')
|
|||
};
|
||||
|
||||
service.confirmContainerDeletion = function(title, callback) {
|
||||
service.prompt({
|
||||
prompt({
|
||||
title: title,
|
||||
inputType: 'checkbox',
|
||||
inputOptions: [
|
||||
|
@ -132,7 +134,7 @@ angular.module('portainer.app')
|
|||
};
|
||||
|
||||
service.confirmContainerRecreation = function(callback) {
|
||||
service.customPrompt({
|
||||
customPrompt({
|
||||
title: 'Are you sure?',
|
||||
message: 'You\'re about to re-create this container, any non-persisted data will be lost. This container will be removed and another one will be created using the same configuration.',
|
||||
inputType: 'checkbox',
|
||||
|
@ -181,7 +183,7 @@ angular.module('portainer.app')
|
|||
};
|
||||
|
||||
service.confirmServiceForceUpdate = function(message, callback) {
|
||||
service.customPrompt({
|
||||
customPrompt({
|
||||
title: 'Are you sure ?',
|
||||
message: message,
|
||||
inputType: 'checkbox',
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'ui-select/dist/select.css';
|
||||
import 'bootstrap/dist/css/bootstrap.css';
|
||||
import 'isteven-angular-multiselect/isteven-multi-select.css';
|
||||
import '@fortawesome/fontawesome-free-webfonts/css/fa-brands.css';
|
||||
import '@fortawesome/fontawesome-free-webfonts/css/fa-solid.css';
|
||||
import '@fortawesome/fontawesome-free-webfonts/css/fontawesome.css';
|
||||
|
@ -19,7 +18,6 @@ window.angular = angular;
|
|||
import 'moment';
|
||||
import '@uirouter/angularjs';
|
||||
import 'ui-select';
|
||||
import 'isteven-angular-multiselect/isteven-multi-select.js';
|
||||
import 'angular-cookies';
|
||||
import 'angular-sanitize';
|
||||
import 'ng-file-upload';
|
||||
|
|
|
@ -71,7 +71,6 @@
|
|||
"chart.js": "~2.6.0",
|
||||
"codemirror": "~5.30.0",
|
||||
"filesize": "~3.3.0",
|
||||
"isteven-angular-multiselect": "~4.0.0",
|
||||
"jquery": "3.4.0",
|
||||
"js-yaml": "~3.13.1",
|
||||
"lodash-es": "^4.17.15",
|
||||
|
|
|
@ -6492,11 +6492,6 @@ istanbul@~0.1.40:
|
|||
which "1.0.x"
|
||||
wordwrap "0.0.x"
|
||||
|
||||
isteven-angular-multiselect@~4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isteven-angular-multiselect/-/isteven-angular-multiselect-4.0.0.tgz#70276da5ff3bc4d9a0887dc585ee26a1a26a8ed6"
|
||||
integrity sha1-cCdtpf87xNmgiH3Fhe4moaJqjtY=
|
||||
|
||||
isurl@^1.0.0-alpha5:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
|
||||
|
|
Loading…
Reference in New Issue