Issues (524)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

js/containers/DeployModal.jsx (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
const React = require('react');
2
const ReactRedux = require('react-redux');
3
4
const StepMenu = require('../components/StepMenu.jsx');
5
const TargetRelease = require('./TargetRelease.jsx');
6
const TargetReleaseRO = require('./TargetReleaseRO.jsx');
7
8
const Approval = require('./Approval.jsx');
9
const ApprovalRO = require('./ApprovalRO.jsx');
10
const Deployment = require('./Deployment.jsx');
11
const DeployPlan = require('./DeployPlan.jsx');
12
const DeployPlanRO = require('./DeployPlanRO.jsx');
13
const Modal = require('../Modal.jsx');
14
const LoadingBar = require('../components/LoadingBar.jsx');
15
16
const actions = require('../_actions.js');
17
const constants = require('../constants/deployment.js');
18
19
function calculateSteps(props) {
20
	return [
21
		{
22
			title: "Target release",
23
			show: props.show[0],
24
			is_finished: props.is_finished[0]
25
		},
26
		{
27
			title: "Deployment plan",
28
			show: props.show[1],
29
			is_finished: props.is_finished[1]
30
		},
31
		{
32
			title: "Approval",
33
			show: props.show[2],
34
			is_finished: props.is_finished[2]
35
		},
36
		{
37
			title: "Deployment",
38
			show: props.show[3],
39
			is_finished: props.is_finished[3]
40
		}
41
	];
42
}
43
44
45
const DeployModal = React.createClass({
46
47
	componentDidMount: function() {
48
		window.addEventListener("resize", this.resize);
49
		const bodyElements = document.getElementsByClassName("modal-body");
50
		if (bodyElements.length === 0) {
51
			return;
52
		}
53
54
		this.resize();
55
	},
56
57
	componentWillUpdate: function() {
58
		// Before we update, we save the current scroll "position" for use in componentDidUpdate
59
		this.saveScrollPosition();
60
	},
61
62
	componentDidUpdate: function(prevProps) {
63
		this.resize();
64
		// when the layout changes from write to readonly we ensure that the modal is scrolled to the same position
65
		// relative to the bottom to prevent a jarring jump. This happens when sending for approval or bypassing the
66
		// approval step.
67
		if (prevProps.can_edit !== this.props.can_edit) {
68
			this.resumeScrollPosition();
69
		}
70
	},
71
72
	componentWillUnmount: function() {
73
		window.removeEventListener("resize", this.resize);
74
	},
75
76
	bodyElement: null,
77
78
	// calculate and set a pixel value on the modal height instead of a percentage
79
	// value so that we get a scrollbar inside the body of the modal
80
	resize: function() {
81
		// We need to calculate the height of the ".modal .body" in the browsers window
82
		let headerHeight = 0;
83
		const headerElements = document.getElementsByClassName("modal-header");
84
		if (headerElements.length > 0) {
85
			headerHeight = headerElements[0].offsetHeight;
86
		}
87
		const bodyElements = document.getElementsByClassName("modal-body");
88
		let bodyHeight = 0;
89
		if (bodyElements.length > 0) {
90
			// leave 16px of space to the bottom of the window
91
			bodyHeight = (window.innerHeight - headerHeight) - 16;
92
		}
93
94
		if (bodyHeight === 0) {
95
			return;
96
		}
97
98
		// Increase the height of the modal, this cannot be done reliable in CSS because
99
		// a pixel value is required to use the "sticky" side bar
100
		bodyElements[0].style.height = bodyHeight + 'px';
101
		// give some space at the bottom so user can scroll
102
		bodyElements[0].style.paddingBottom = (bodyHeight / 10) + 'px';
103
	},
104
105
	scrollHeight: 0,
106
107
	scrollTop: 0,
108
109
	// save the current scroll position
110
	saveScrollPosition() {
111
		const node = document.getElementsByClassName("modal-body");
112
		if (node.length > 0) {
113
			this.scrollHeight = node[0].scrollHeight;
114
			this.scrollTop = node[0].scrollTop;
115
		}
116
	},
117
118
	// scroll the modal window body to the position previously saved in saveScrollPosition() relative
119
	// to the bottom. This will prevent the content jumping if content above the current scroll position
120
	// changes height.
121
	resumeScrollPosition() {
122
		const node = document.getElementsByClassName("modal-body");
123
		if (node.length > 0) {
124
			node[0].scrollTop = this.scrollTop + (node[0].scrollHeight - this.scrollHeight);
125
		}
126
	},
127
128
	render: function() {
129
		const steps = calculateSteps(this.props);
130
		const content = [];
131
132
		content[0] = (
133
			<div key={0} className="section">
134
				<LoadingBar show />
135
			</div>
136
		);
137
138
		if (steps[0].show) {
139
			if (this.props.can_edit) {
140
				content[0] = (<TargetRelease key={0} />);
141
			} else {
142
				content[0] = (<TargetReleaseRO key={0} />);
143
			}
144
		}
145
		if (steps[1].show) {
146
			if (this.props.can_edit) {
147
				content[1] = (<DeployPlan key={1} />);
148
			} else {
149
				content[1] = (<DeployPlanRO key={1} />);
150
			}
151
		}
152
		if (steps[2].show) {
153
			if (this.props.can_edit) {
154
				content[2] = (<Approval key={2} />);
155
			} else {
156
				content[2] = (<ApprovalRO key={2} />);
157
			}
158
		}
159
		if (steps[3].show) {
160
			content[3] = (<Deployment key={3} />);
161
		}
162
163
		const options = [];
164
		if (this.props.deployment_id && constants.canDelete(this.props.state)) {
165
			options.push({
166
				title: 'Delete',
167
				icon: 'fa fa-trash',
168
				handler: this.props.onDelete
169
			});
170
		}
171
172
		let headerText = `Deployment to ${this.props.project_name} / ${this.props.environment_name}`;
173
		switch (this.props.state) {
0 ignored issues
show
Expected a default case.
Loading history...
174
			case constants.STATE_COMPLETED: {
175
				headerText += ` completed on ${this.props.deployment.date_started_nice}`;
176
				break;
177
			}
178
			case constants.STATE_FAILED: {
179
				headerText += ` failed at ${this.props.deployment.date_started_nice}`;
180
				break;
181
			}
182
			case constants.STATE_REJECTED: {
183
				headerText += ' has been rejected';
184
				break;
185
			}
186
			case constants.STATE_APPROVED: {
187
				headerText += ' is ready';
188
				break;
189
			}
190
			case constants.STATE_QUEUED:
191
			case constants.STATE_DEPLOYING: {
192
				headerText += ' in progress...';
193
				break;
194
			}
195
			case constants.STATE_SUBMITTED:
196
				headerText += ' is awaiting approval';
197
				break;
198
		}
199
200
		return (
201
			<Modal
202
				show={this.props.is_open}
203
				className={"deploy status-" + this.props.state}
204
				closeHandler={this.props.onClose}
205
				title={headerText}
206
				closeTitle="Close"
207
				options={options}
208
			>
209
				<div className="row">
210
					<div className="col-md-3 menu affix">
211
						<StepMenu
212
							steps={steps}
213
							onClick={this.props.onStepClick}
214
						/>
215
					</div>
216
					<div className="col-md-9 main" >
217
						<div className="deploy-form">
218
							<div>
219
								{content}
220
							</div>
221
						</div>
222
					</div>
223
				</div>
224
			</Modal>
225
		);
226
	}
227
});
228
229
const mapStateToProps = function(state, ownProps) {
230
	function deployPlanIsOk() {
231
		return state.plan.validation_code === 'success' || state.plan.validation_code === 'warning';
232
	}
233
234
	const current = state.deployment.list[state.deployment.current_id] || {};
235
236
	const showPlan = state.git.selected_ref !== "" && (typeof state.plan.changes === "object");
237
	const showApproval = state.deployment.current_id !== "" && current.dirty === false;
238
239
	return {
240
		show: [
241
			(!state.git.is_loading && !state.deployment.is_loading),
242
			showPlan,
243
			showPlan && showApproval,
244
			constants.isApproved(current.state)
245
		],
246
		is_finished: [
247
			deployPlanIsOk() && state.git.selected_ref !== "",
248
			deployPlanIsOk() && state.deployment.current_id !== "",
249
			deployPlanIsOk() && constants.isApproved(current.state),
250
			constants.isDeployDone(current.state)
251
		],
252
		can_edit: constants.canEdit(state),
253
		is_open: typeof (ownProps.params.id) !== 'undefined' && ownProps.params.id !== null,
254
		state: current.state,
255
		environment_name: state.environment.name,
256
		project_name: state.environment.project_name,
257
		deployment_id: state.deployment.current_id,
258
		deployment: current
259
	};
260
};
261
262
const mapDispatchToProps = function(dispatch) {
263
	return {
264
		onClose: function() {
265
			actions.history.push('/');
266
		},
267
		onDelete: function() {
268
			dispatch(actions.deleteDeployment())
269
				.then(() => actions.history.push('/'));
270
		}
271
	};
272
};
273
274
module.exports = ReactRedux.connect(mapStateToProps, mapDispatchToProps)(DeployModal);
275