@@ -104,7 +104,11 @@ export default class Page extends React.PureComponent<Props> { | |||
</Helmet> | |||
<HeaderList headers={realHeadingsList} /> | |||
<h1>{pageTitle || mainTitle}</h1> | |||
<div className="markdown-content" dangerouslySetInnerHTML={{ __html: htmlPageContent }} /> | |||
<div | |||
className="markdown-content" | |||
// Safe: comes from the backend | |||
dangerouslySetInnerHTML={{ __html: htmlPageContent }} | |||
/> | |||
</> | |||
); | |||
} |
@@ -5,6 +5,7 @@ | |||
"repository": "SonarSource/sonarqube", | |||
"license": "LGPL-3.0", | |||
"dependencies": { | |||
"@types/dompurify": "^0.0.32", | |||
"classnames": "2.2.6", | |||
"clipboard": "2.0.1", | |||
"core-js": "3.0.0", | |||
@@ -16,6 +17,7 @@ | |||
"d3-shape": "1.2.2", | |||
"d3-zoom": "1.7.3", | |||
"date-fns": "1.29.0", | |||
"dompurify": "^1.0.11", | |||
"formik": "1.2.0", | |||
"history": "3.3.0", | |||
"intl-relativeformat": "2.1.0", | |||
@@ -78,6 +80,7 @@ | |||
"@types/react-router": "3.0.20", | |||
"@types/react-select": "1.2.6", | |||
"@types/react-virtualized": "9.21.0", | |||
"@types/sanitize-html": "1.20.0", | |||
"@types/valid-url": "1.0.2", | |||
"@typescript-eslint/parser": "1.5.0", | |||
"autoprefixer": "9.5.0", |
@@ -137,6 +137,7 @@ export default class SearchResult extends React.PureComponent<Props, State> { | |||
{component.match ? ( | |||
<span | |||
className="navbar-search-item-match" | |||
// Safe: comes from the backend | |||
dangerouslySetInnerHTML={{ __html: component.match }} | |||
/> | |||
) : ( |
@@ -18,9 +18,10 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import * as classNames from 'classnames'; | |||
import DeferredSpinner from '../../../components/common/DeferredSpinner'; | |||
import { translate, translateWithParameters } from '../../../helpers/l10n'; | |||
import { translate } from '../../../helpers/l10n'; | |||
interface Props { | |||
allowMore: boolean; | |||
@@ -61,15 +62,15 @@ export default class SearchShowMore extends React.PureComponent<Props> { | |||
href="#" | |||
onClick={this.handleMoreClick} | |||
onMouseEnter={this.handleMoreMouseEnter}> | |||
<div | |||
className="pull-right text-muted-2 menu-footer-note" | |||
dangerouslySetInnerHTML={{ | |||
__html: translateWithParameters( | |||
'search.show_more.hint', | |||
'<span class="shortcut-button shortcut-button-small">Enter</span>' | |||
) | |||
}} | |||
/> | |||
<div className="pull-right text-muted-2 menu-footer-note"> | |||
<FormattedMessage | |||
defaultMessage={translate('search.show_more.hint')} | |||
id={'search.show_more.hint'} | |||
values={{ | |||
key: <span className="shortcut-button shortcut-button-small">Enter</span> | |||
}} | |||
/> | |||
</div> | |||
<span>{translate('show_more')}</span> | |||
</a> | |||
</DeferredSpinner> |
@@ -19,12 +19,21 @@ exports[`should render 1`] = ` | |||
> | |||
<div | |||
className="pull-right text-muted-2 menu-footer-note" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "search.show_more.hint.<span class=\\"shortcut-button shortcut-button-small\\">Enter</span>", | |||
> | |||
<FormattedMessage | |||
defaultMessage="search.show_more.hint" | |||
id="search.show_more.hint" | |||
values={ | |||
Object { | |||
"key": <span | |||
className="shortcut-button shortcut-button-small" | |||
> | |||
Enter | |||
</span>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</div> | |||
<span> | |||
show_more | |||
</span> |
@@ -158,7 +158,11 @@ export class AboutApp extends React.PureComponent<Props, State> { | |||
</div> | |||
{customText && ( | |||
<div className="about-page-section" dangerouslySetInnerHTML={{ __html: customText }} /> | |||
<div | |||
className="about-page-section" | |||
// Safe: Defined by instance admin | |||
dangerouslySetInnerHTML={{ __html: customText }} | |||
/> | |||
)} | |||
<AboutLanguages /> |
@@ -224,6 +224,7 @@ export default class ActivationFormModal extends React.PureComponent<Props, Stat | |||
)} | |||
<div | |||
className="note" | |||
// Safe: defined by rule creator (instance admin?) | |||
dangerouslySetInnerHTML={{ __html: param.htmlDesc || '' }} | |||
/> | |||
</div> |
@@ -304,6 +304,7 @@ export default class CustomRuleFormModal extends React.PureComponent<Props, Stat | |||
)} | |||
<div | |||
className="modal-field-description" | |||
// Safe: defined by rule creator (instance admin?) | |||
dangerouslySetInnerHTML={{ __html: param.htmlDesc || '' }} | |||
/> | |||
</div> |
@@ -112,6 +112,7 @@ export default class RuleDetailsDescription extends React.PureComponent<Props, S | |||
{this.props.ruleDetails.htmlNote !== undefined && ( | |||
<div | |||
className="rule-desc spacer-bottom markdown" | |||
// Safe: defined by rule creator (instance admin?) | |||
dangerouslySetInnerHTML={{ __html: this.props.ruleDetails.htmlNote }} | |||
/> | |||
)} | |||
@@ -193,6 +194,7 @@ export default class RuleDetailsDescription extends React.PureComponent<Props, S | |||
{hasDescription ? ( | |||
<div | |||
className="coding-rules-detail-description rule-desc markdown" | |||
// Safe: defined by rule creator (instance admin?) | |||
dangerouslySetInnerHTML={{ __html: ruleDetails.htmlDesc || '' }} | |||
/> | |||
) : ( |
@@ -29,7 +29,9 @@ export default class RuleDetailsParameters extends React.PureComponent<Props> { | |||
<tr className="coding-rules-detail-parameter" key={param.key}> | |||
<td className="coding-rules-detail-parameter-name">{param.key}</td> | |||
<td className="coding-rules-detail-parameter-description"> | |||
<p dangerouslySetInnerHTML={{ __html: param.htmlDesc || '' }} /> | |||
<p // Safe: defined by rule creator (instance admin?) | |||
dangerouslySetInnerHTML={{ __html: param.htmlDesc || '' }} | |||
/> | |||
{param.defaultValue !== undefined && ( | |||
<div className="note spacer-top"> | |||
{translate('coding_rules.parameters.default_value')} |
@@ -0,0 +1,33 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import RuleDetailsParameters from '../RuleDetailsParameters'; | |||
import { mockRuleDetailsParameter } from '../../../../helpers/testMocks'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<RuleDetailsParameters['props']> = {}) { | |||
const params = [mockRuleDetailsParameter(), mockRuleDetailsParameter()]; | |||
return shallow(<RuleDetailsParameters params={params} {...props} />); | |||
} |
@@ -0,0 +1,83 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<div | |||
className="js-rule-parameters" | |||
> | |||
<h3 | |||
className="coding-rules-detail-title" | |||
> | |||
coding_rules.parameters | |||
</h3> | |||
<table | |||
className="coding-rules-detail-parameters" | |||
> | |||
<tbody> | |||
<tr | |||
className="coding-rules-detail-parameter" | |||
key="1" | |||
> | |||
<td | |||
className="coding-rules-detail-parameter-name" | |||
> | |||
1 | |||
</td> | |||
<td | |||
className="coding-rules-detail-parameter-description" | |||
> | |||
<p | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "description", | |||
} | |||
} | |||
/> | |||
<div | |||
className="note spacer-top" | |||
> | |||
coding_rules.parameters.default_value | |||
<br /> | |||
<span | |||
className="coding-rules-detail-parameter-value" | |||
> | |||
1 | |||
</span> | |||
</div> | |||
</td> | |||
</tr> | |||
<tr | |||
className="coding-rules-detail-parameter" | |||
key="1" | |||
> | |||
<td | |||
className="coding-rules-detail-parameter-name" | |||
> | |||
1 | |||
</td> | |||
<td | |||
className="coding-rules-detail-parameter-description" | |||
> | |||
<p | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "description", | |||
} | |||
} | |||
/> | |||
<div | |||
className="note spacer-top" | |||
> | |||
coding_rules.parameters.default_value | |||
<br /> | |||
<span | |||
className="coding-rules-detail-parameter-value" | |||
> | |||
1 | |||
</span> | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
`; |
@@ -119,6 +119,7 @@ export default class IssuesSourceViewer extends React.PureComponent<Props> { | |||
const component = selectedLocation ? selectedLocation.component : openIssue.component; | |||
const allMessagesEmpty = | |||
locations !== undefined && locations.every(location => !location.msg); | |||
const highlightedLocations = locations.filter(location => location.component === component); | |||
// do not load issues when open another file for a location |
@@ -18,8 +18,9 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import * as classNames from 'classnames'; | |||
import Helmet from 'react-helmet'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import * as classNames from 'classnames'; | |||
import { getMigrationStatus, getSystemStatus, migrateDatabase } from '../../../api/system'; | |||
import DateFromNow from '../../../components/intl/DateFromNow'; | |||
import TimeFormatter from '../../../components/intl/TimeFormatter'; | |||
@@ -201,18 +202,32 @@ export default class App extends React.PureComponent<Props, State> { | |||
</h1> | |||
{!isSonarCloud() && ( | |||
<> | |||
<p | |||
className="maintenance-text" | |||
dangerouslySetInnerHTML={{ | |||
__html: translate('maintenance.sonarqube_is_under_maintenance.1') | |||
}} | |||
/> | |||
<p | |||
className="maintenance-text" | |||
dangerouslySetInnerHTML={{ | |||
__html: translate('maintenance.sonarqube_is_under_maintenance.2') | |||
}} | |||
/> | |||
<p className="maintenance-text"> | |||
<FormattedMessage | |||
defaultMessage={translate('maintenance.sonarqube_is_under_maintenance.1')} | |||
id="maintenance.sonarqube_is_under_maintenance.1" | |||
values={{ | |||
link: ( | |||
<a href="https://redirect.sonarsource.com/doc/plugin-library.html"> | |||
{translate('maintenance.sonarqube_is_under_maintenance_link.1')} | |||
</a> | |||
) | |||
}} | |||
/> | |||
</p> | |||
<p className="maintenance-text"> | |||
<FormattedMessage | |||
defaultMessage={translate('maintenance.sonarqube_is_under_maintenance.2')} | |||
id="maintenance.sonarqube_is_under_maintenance.2" | |||
values={{ | |||
link: ( | |||
<a href="https://redirect.sonarsource.com/doc/upgrading.html"> | |||
{translate('maintenance.sonarqube_is_under_maintenance_link.2')} | |||
</a> | |||
) | |||
}} | |||
/> | |||
</p> | |||
</> | |||
)} | |||
</> |
@@ -24,20 +24,38 @@ exports[`Maintenance Page should render DB_MIGRATION_NEEDED status 1`] = ` | |||
</h1> | |||
<p | |||
className="maintenance-text" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "maintenance.sonarqube_is_under_maintenance.1", | |||
> | |||
<FormattedMessage | |||
defaultMessage="maintenance.sonarqube_is_under_maintenance.1" | |||
id="maintenance.sonarqube_is_under_maintenance.1" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="https://redirect.sonarsource.com/doc/plugin-library.html" | |||
> | |||
maintenance.sonarqube_is_under_maintenance_link.1 | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p | |||
className="maintenance-text" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "maintenance.sonarqube_is_under_maintenance.2", | |||
> | |||
<FormattedMessage | |||
defaultMessage="maintenance.sonarqube_is_under_maintenance.2" | |||
id="maintenance.sonarqube_is_under_maintenance.2" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="https://redirect.sonarsource.com/doc/upgrading.html" | |||
> | |||
maintenance.sonarqube_is_under_maintenance_link.2 | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
</div> | |||
</Fragment> | |||
@@ -67,20 +85,38 @@ exports[`Maintenance Page should render DB_MIGRATION_RUNNING status 1`] = ` | |||
</h1> | |||
<p | |||
className="maintenance-text" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "maintenance.sonarqube_is_under_maintenance.1", | |||
> | |||
<FormattedMessage | |||
defaultMessage="maintenance.sonarqube_is_under_maintenance.1" | |||
id="maintenance.sonarqube_is_under_maintenance.1" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="https://redirect.sonarsource.com/doc/plugin-library.html" | |||
> | |||
maintenance.sonarqube_is_under_maintenance_link.1 | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p | |||
className="maintenance-text" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "maintenance.sonarqube_is_under_maintenance.2", | |||
> | |||
<FormattedMessage | |||
defaultMessage="maintenance.sonarqube_is_under_maintenance.2" | |||
id="maintenance.sonarqube_is_under_maintenance.2" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="https://redirect.sonarsource.com/doc/upgrading.html" | |||
> | |||
maintenance.sonarqube_is_under_maintenance_link.2 | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
</div> | |||
</Fragment> |
@@ -21,6 +21,7 @@ import * as React from 'react'; | |||
import { setSimpleSettingValue, resetSettingValue } from '../../../api/settings'; | |||
import { Button, SubmitButton, ResetButtonLink } from '../../../components/ui/buttons'; | |||
import { translate, translateWithParameters } from '../../../helpers/l10n'; | |||
import { sanitizeTranslation } from '../../settings/utils'; | |||
interface Props { | |||
branch?: string; | |||
@@ -96,7 +97,9 @@ export default class SettingForm extends React.PureComponent<Props, State> { | |||
<div className="modal-body"> | |||
<div | |||
className="big-spacer-bottom markdown" | |||
dangerouslySetInnerHTML={{ __html: translate(`property.${setting.key}.description`) }} | |||
dangerouslySetInnerHTML={{ | |||
__html: sanitizeTranslation(translate(`property.${setting.key}.description`)) | |||
}} | |||
/> | |||
<div className="modal-field"> | |||
<input |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { getEmptyValue, getDefaultValue } from '../utils'; | |||
import { getEmptyValue, getDefaultValue, sanitizeTranslation } from '../utils'; | |||
const fields = [ | |||
{ key: 'foo', type: 'STRING' } as T.SettingFieldDefinition, | |||
@@ -76,3 +76,106 @@ describe('#getDefaultValue()', () => { | |||
it('should work for boolean field when passing "false"', () => | |||
check('false', 'settings.boolean.false')); | |||
}); | |||
describe('sanitizeTranslation', () => { | |||
it('should preserve formatting tags', () => { | |||
const allowed = ` | |||
Hi this is <i>in italics</i> and <ul> | |||
<li> lists </li> | |||
<li> are allowed</li> | |||
</ul> | |||
<p> | |||
as well. This is <b>Amazing</b> and this <strong>bold</strong> <br> | |||
and <code>code.is.accepted too</code> | |||
</p> | |||
`; | |||
const clean = sanitizeTranslation(allowed); | |||
expect(clean).toBe(allowed); | |||
}); | |||
/* | |||
* Test code borrowed from OWASP's sanitizer tests | |||
* https://github.com/OWASP/java-html-sanitizer/blob/master/src/test/resources/org/owasp/html/htmllexerinput1.html | |||
*/ | |||
it('should strip everything else', () => { | |||
const clean = sanitizeTranslation(`<?xml version="not-even-close"?> | |||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |||
<!-- a test input for HtmlLexer --> | |||
<html> | |||
<head> | |||
<title>Test File For HtmlLexer & HtmlParser</title> | |||
<link rel=stylesheet type="text/css" src=foo/bar.css /> | |||
<body | |||
bgcolor=white | |||
linkcolor = "blue" | |||
onload="document.writeln( | |||
"<p>properly escaped code in a handler</p>");" | |||
> | |||
<script type="text/javascript"><!-- | |||
document.writeln("<p>Some initialization code in global context</p>"); | |||
--></script> | |||
<script type="text/javascript"> | |||
// hi there | |||
document.writeln("<p>More initialization</p>"); | |||
</script> | |||
<div id=clickydiv onclick="handleClicky(event)" | |||
ondblclick=this.onclick(event);return(false)> | |||
Clicky | |||
</div> | |||
<input id=foo> | |||
<gxp:attr name="onchange">alert("<b>hi</b>");</gxp:attr> | |||
</input> | |||
<pre><div id=notarealtag onclick=notcode()></pre> | |||
<!-- some tokenization corner cases --> | |||
< notatag <atag/> | |||
</ notatag> </redundantlyclosed/> | |||
<messyattributes a=b=c d="e"f=g h =i j= k l = m checked n="o"/> | |||
< < < all in one text block > > > | |||
<xmp>Make sure that <!-- comments don't obscure the xmp close</xmp> | |||
<% # some php code here | |||
write("<pre>$horriblySyntacticConstruct1</pre>\n\n"); | |||
%> | |||
<script type="text/javascript"><!-- | |||
alert("hello world"); | |||
// --></script> | |||
<script>/* </script> */alert('hi');</script> | |||
<script><!--/* </script> */alert('hi');--></script> | |||
<xmp style=color:blue><!--/* </xmp> */alert('hi');--></xmp> | |||
<style><!-- p { contentf: '</style>' } --></style> | |||
<style>Foo<!-- > </style> --></style> | |||
<textarea><!-- Zoicks </textarea>--></textarea> | |||
<!-- An escaping text span start may share its U+002D HYPHEN-MINUS characters | |||
- with its corresponding escaping text span end. --> | |||
<script><!--></script> | |||
<script><!---></script> | |||
<script><!----></script> | |||
</body> | |||
</html> | |||
<![CDATA[ No such thing as a CDATA> section in HTML ]]> | |||
<script>a<b</script> | |||
<img src=foo.gif /><a href=><a href=/> | |||
<span title=malformed attribs' do=don't id=foo checked onclick="a<b">Bar</span>`); | |||
expect(clean.replace(/\s+/g, '')).toBe( | |||
`Clickyalert("<b>hi</b>");<divid=notarealtagonclick=notcode()><notatag<<<allinonetextblock>>>Makesurethat<%#somephpcodeherewrite("$horriblySyntacticConstruct1");%>*/alert('hi');*/alert('hi');-->*/alert('hi');-->'}-->--><!--Zoicks-->sectioninHTML]]>Bar` | |||
); | |||
}); | |||
}); |
@@ -26,7 +26,8 @@ import { | |||
getPropertyName, | |||
getPropertyDescription, | |||
getSettingValue, | |||
isDefaultOrInherited | |||
isDefaultOrInherited, | |||
sanitizeTranslation | |||
} from '../utils'; | |||
import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon'; | |||
import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon'; | |||
@@ -142,7 +143,7 @@ export class Definition extends React.PureComponent<Props, State> { | |||
{description && ( | |||
<div | |||
className="markdown small spacer-top" | |||
dangerouslySetInnerHTML={{ __html: description }} | |||
dangerouslySetInnerHTML={{ __html: sanitizeTranslation(description) }} | |||
/> | |||
)} | |||
@@ -21,7 +21,7 @@ import * as React from 'react'; | |||
import { groupBy, isEqual, sortBy } from 'lodash'; | |||
import DefinitionsList from './DefinitionsList'; | |||
import EmailForm from './EmailForm'; | |||
import { getSubCategoryName, getSubCategoryDescription } from '../utils'; | |||
import { getSubCategoryName, getSubCategoryDescription, sanitizeTranslation } from '../utils'; | |||
interface Props { | |||
category: string; | |||
@@ -74,7 +74,7 @@ export default class SubCategoryDefinitionsList extends React.PureComponent<Prop | |||
{subCategory.description != null && ( | |||
<div | |||
className="settings-sub-category-description markdown" | |||
dangerouslySetInnerHTML={{ __html: subCategory.description }} | |||
dangerouslySetInnerHTML={{ __html: sanitizeTranslation(subCategory.description) }} | |||
/> | |||
)} | |||
<DefinitionsList |
@@ -76,10 +76,32 @@ export default class GenerateSecretKeyForm extends React.PureComponent<Props, St | |||
<ClipboardButton className="little-spacer-left" copyValue={secretKey} /> | |||
</div> | |||
<h3 className="spacer-bottom">{translate('encryption.how_to_use')}</h3> | |||
<div | |||
className="markdown" | |||
dangerouslySetInnerHTML={{ __html: translate('encryption.how_to_use.content') }} | |||
/> | |||
<div className="markdown"> | |||
<ul> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage={translate('encryption.how_to_use.content1')} | |||
id="encryption.how_to_use.content1" | |||
values={{ | |||
secret_file: <code>~/.sonar/sonar-secret.txt</code>, | |||
property: <code>sonar.secretKeyPath</code>, | |||
propreties_file: <code>conf/sonar.properties</code> | |||
}} | |||
/> | |||
</li> | |||
<li>{translate('encryption.how_to_use.content2')}</li> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage={translate('encryption.how_to_use.content3')} | |||
id="encryption.how_to_use.content3" | |||
values={{ | |||
property: <code>sonar.secretKeyPath</code> | |||
}} | |||
/> | |||
</li> | |||
<li>{translate('encryption.how_to_use.content4')}</li> | |||
</ul> | |||
</div> | |||
</> | |||
) : ( | |||
<form id="generate-secret-key-form" onSubmit={this.handleSubmit}> |
@@ -17,6 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { sanitize } from 'dompurify'; | |||
import { translate, hasMessage } from '../../helpers/l10n'; | |||
export const DEFAULT_CATEGORY = 'general'; | |||
@@ -35,6 +36,12 @@ export interface DefaultInputProps { | |||
value: any; | |||
} | |||
export function sanitizeTranslation(html: string) { | |||
return sanitize(html, { | |||
ALLOWED_TAGS: ['b', 'br', 'code', 'i', 'li', 'p', 'strong', 'ul'] | |||
}); | |||
} | |||
export function getPropertyName(definition: T.SettingDefinition) { | |||
const key = `property.${definition.key}.name`; | |||
return hasMessage(key) ? translate(key) : definition.name; |
@@ -18,6 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { translate } from '../../../../helpers/l10n'; | |||
import { getBaseUrl } from '../../../../helpers/urls'; | |||
@@ -38,12 +39,15 @@ export default function BuildWrapper(props: Props) { | |||
<h4 className="spacer-bottom"> | |||
{translate('onboarding.analysis.build_wrapper.header', props.os)} | |||
</h4> | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={{ | |||
__html: translate('onboarding.analysis.build_wrapper.text', props.os) | |||
}} | |||
/> | |||
<p className="spacer-bottom markdown"> | |||
<FormattedMessage | |||
defaultMessage={translate('onboarding.analysis.build_wrapper.text')} | |||
id="onboarding.analysis.build_wrapper.text" | |||
values={{ | |||
env_var: <code>{props.os === 'win' ? '%PATH%' : 'PATH'}</code> | |||
}} | |||
/> | |||
</p> | |||
<p> | |||
<a | |||
className="button" |
@@ -18,6 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import SQScanner from './SQScanner'; | |||
import BuildWrapper from './BuildWrapper'; | |||
import CodeSnippet from '../../../../components/common/CodeSnippet'; | |||
@@ -63,19 +64,26 @@ export default function ClangGCC(props: Props) { | |||
{translate('onboarding.analysis.sq_scanner.execute')} | |||
</h4> | |||
<InstanceMessage message={translate('onboarding.analysis.sq_scanner.execute.text')}> | |||
{transformedMessage => ( | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={{ __html: transformedMessage }} | |||
/> | |||
)} | |||
{transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>} | |||
</InstanceMessage> | |||
<CodeSnippet isOneLine={props.small} snippet={command1} /> | |||
<CodeSnippet isOneLine={props.os === 'win'} snippet={command2} /> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.sq_scanner.docs') }} | |||
/> | |||
<p className="big-spacer-top markdown"> | |||
<FormattedMessage | |||
defaultMessage={translate('onboarding.analysis.sq_scanner.docs')} | |||
id="onboarding.analysis.sq_scanner.docs" | |||
values={{ | |||
link: ( | |||
<a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
{translate('onboarding.analysis.sq_scanner.docs_link')} | |||
</a> | |||
) | |||
}} | |||
/> | |||
</p> | |||
</div> | |||
); | |||
} |
@@ -18,6 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import MSBuildScanner from './MSBuildScanner'; | |||
import CodeSnippet from '../../../../components/common/CodeSnippet'; | |||
import InstanceMessage from '../../../../components/common/InstanceMessage'; | |||
@@ -52,20 +53,27 @@ export default function DotNet(props: Props) { | |||
{translate('onboarding.analysis.msbuild.execute')} | |||
</h4> | |||
<InstanceMessage message={translate('onboarding.analysis.msbuild.execute.text')}> | |||
{transformedMessage => ( | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={{ __html: transformedMessage }} | |||
/> | |||
)} | |||
{transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>} | |||
</InstanceMessage> | |||
<CodeSnippet isOneLine={true} snippet={command1} /> | |||
<CodeSnippet isOneLine={false} snippet={command2} /> | |||
<CodeSnippet isOneLine={props.small} snippet={command3} /> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.docs') }} | |||
/> | |||
<p className="big-spacer-top markdown"> | |||
<FormattedMessage | |||
defaultMessage={translate('onboarding.analysis.docs')} | |||
id="onboarding.analysis.docs" | |||
values={{ | |||
link: ( | |||
<a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html" | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
{translate('onboarding.analysis.msbuild.docs_link')} | |||
</a> | |||
) | |||
}} | |||
/> | |||
</p> | |||
</div> | |||
); | |||
} |
@@ -18,6 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import CodeSnippet from '../../../../components/common/CodeSnippet'; | |||
import InstanceMessage from '../../../../components/common/InstanceMessage'; | |||
import { translate } from '../../../../helpers/l10n'; | |||
@@ -45,10 +46,16 @@ export default function JavaGradle(props: Props) { | |||
<h4 className="spacer-bottom">{translate('onboarding.analysis.java.gradle.header')}</h4> | |||
<InstanceMessage message={translate('onboarding.analysis.java.gradle.text.1')}> | |||
{transformedMessage => ( | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={{ __html: transformedMessage }} | |||
/> | |||
<p className="spacer-bottom markdown"> | |||
<FormattedMessage | |||
defaultMessage={transformedMessage} | |||
id="onboarding.analysis.java.gradle.text.1" | |||
values={{ | |||
plugin_code: <code>org.sonarqube</code>, | |||
filename: <code>build.gradle</code> | |||
}} | |||
/> | |||
</p> | |||
)} | |||
</InstanceMessage> | |||
<CodeSnippet snippet={config} /> | |||
@@ -56,18 +63,27 @@ export default function JavaGradle(props: Props) { | |||
{translate('onboarding.analysis.java.gradle.text.2')} | |||
</p> | |||
<CodeSnippet snippet={command} /> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.java.gradle.docs') }} | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={{ | |||
__html: props.projectKey | |||
? translate('onboarding.analysis.auto_refresh_after_analysis') | |||
: translate('onboarding.analysis.browse_url_after_analysis') | |||
}} | |||
/> | |||
<p className="big-spacer-top markdown"> | |||
<FormattedMessage | |||
defaultMessage={translate('onboarding.analysis.docs')} | |||
id="onboarding.analysis.docs" | |||
values={{ | |||
link: ( | |||
<a | |||
href="http://redirect.sonarsource.com/doc/gradle.html" | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
{translate('onboarding.analysis.java.gradle.docs_link')} | |||
</a> | |||
) | |||
}} | |||
/> | |||
</p> | |||
<p className="big-spacer-top markdown"> | |||
{props.projectKey | |||
? translate('onboarding.analysis.auto_refresh_after_analysis') | |||
: translate('onboarding.analysis.browse_url_after_analysis')} | |||
</p> | |||
</div> | |||
); | |||
} |
@@ -18,6 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import CodeSnippet from '../../../../components/common/CodeSnippet'; | |||
import InstanceMessage from '../../../../components/common/InstanceMessage'; | |||
import { translate } from '../../../../helpers/l10n'; | |||
@@ -45,18 +46,27 @@ export default function JavaMaven(props: Props) { | |||
<InstanceMessage message={translate('onboarding.analysis.java.maven.text')} /> | |||
</p> | |||
<CodeSnippet snippet={command} /> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.java.maven.docs') }} | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={{ | |||
__html: props.projectKey | |||
? translate('onboarding.analysis.auto_refresh_after_analysis') | |||
: translate('onboarding.analysis.browse_url_after_analysis') | |||
}} | |||
/> | |||
<p className="big-spacer-top markdown"> | |||
<FormattedMessage | |||
defaultMessage={translate('onboarding.analysis.docs')} | |||
id="onboarding.analysis.docs" | |||
values={{ | |||
link: ( | |||
<a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html" | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
{translate('onboarding.analysis.java.maven.docs_link')} | |||
</a> | |||
) | |||
}} | |||
/> | |||
</p> | |||
<p className="big-spacer-top markdown"> | |||
{props.projectKey | |||
? translate('onboarding.analysis.auto_refresh_after_analysis') | |||
: translate('onboarding.analysis.browse_url_after_analysis')} | |||
</p> | |||
</div> | |||
); | |||
} |
@@ -18,6 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { translate } from '../../../../helpers/l10n'; | |||
interface Props { | |||
@@ -28,10 +29,13 @@ export default function MSBuildScanner(props: Props) { | |||
return ( | |||
<div className={props.className}> | |||
<h4 className="spacer-bottom">{translate('onboarding.analysis.msbuild.header')}</h4> | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.text') }} | |||
/> | |||
<p className="spacer-bottom markdown"> | |||
<FormattedMessage | |||
defaultMessage={translate('onboarding.analysis.msbuild.text')} | |||
id="onboarding.analysis.msbuild.text" | |||
values={{ code: <code>%PATH%</code> }} | |||
/> | |||
</p> | |||
<p> | |||
<a | |||
className="button" |
@@ -18,6 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import MSBuildScanner from './MSBuildScanner'; | |||
import BuildWrapper from './BuildWrapper'; | |||
import CodeSnippet from '../../../../components/common/CodeSnippet'; | |||
@@ -55,20 +56,27 @@ export default function Msvc(props: Props) { | |||
{translate('onboarding.analysis.msbuild.execute')} | |||
</h4> | |||
<InstanceMessage message={translate('onboarding.analysis.msbuild.execute.text')}> | |||
{transformedMessage => ( | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={{ __html: transformedMessage }} | |||
/> | |||
)} | |||
{transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>} | |||
</InstanceMessage> | |||
<CodeSnippet isOneLine={true} snippet={command1} /> | |||
<CodeSnippet isOneLine={props.small} snippet={command2} /> | |||
<CodeSnippet isOneLine={props.small} snippet={command3} /> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.docs') }} | |||
/> | |||
<p className="big-spacer-top markdown"> | |||
<FormattedMessage | |||
defaultMessage={translate('onboarding.analysis.docs')} | |||
id="onboarding.analysis.docs" | |||
values={{ | |||
link: ( | |||
<a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html" | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
{translate('onboarding.analysis.msbuild.docs_link')} | |||
</a> | |||
) | |||
}} | |||
/> | |||
</p> | |||
</div> | |||
); | |||
} |
@@ -18,6 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import SQScanner from './SQScanner'; | |||
import CodeSnippet from '../../../../components/common/CodeSnippet'; | |||
import InstanceMessage from '../../../../components/common/InstanceMessage'; | |||
@@ -51,18 +52,25 @@ export default function Other(props: Props) { | |||
{translate('onboarding.analysis.sq_scanner.execute')} | |||
</h4> | |||
<InstanceMessage message={translate('onboarding.analysis.sq_scanner.execute.text')}> | |||
{transformedMessage => ( | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={{ __html: transformedMessage }} | |||
/> | |||
)} | |||
{transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>} | |||
</InstanceMessage> | |||
<CodeSnippet isOneLine={props.os === 'win'} snippet={command} /> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.sq_scanner.docs') }} | |||
/> | |||
<p className="big-spacer-top markdown"> | |||
<FormattedMessage | |||
defaultMessage={translate('onboarding.analysis.sq_scanner.docs')} | |||
id="onboarding.analysis.sq_scanner.docs" | |||
values={{ | |||
link: ( | |||
<a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
{translate('onboarding.analysis.sq_scanner.docs_link')} | |||
</a> | |||
) | |||
}} | |||
/> | |||
</p> | |||
</div> | |||
); | |||
} |
@@ -18,6 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { translate } from '../../../../helpers/l10n'; | |||
interface Props { | |||
@@ -31,12 +32,16 @@ export default function SQScanner(props: Props) { | |||
<h4 className="spacer-bottom"> | |||
{translate('onboarding.analysis.sq_scanner.header', props.os)} | |||
</h4> | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={{ | |||
__html: translate('onboarding.analysis.sq_scanner.text', props.os) | |||
}} | |||
/> | |||
<p className="spacer-bottom markdown"> | |||
<FormattedMessage | |||
defaultMessage={translate('onboarding.analysis.sq_scanner.text')} | |||
id="onboarding.analysis.sq_scanner.text" | |||
values={{ | |||
dir: <code>bin</code>, | |||
env_var: <code>{props.os === 'win' ? '%PATH%' : 'PATH'}</code> | |||
}} | |||
/> | |||
</p> | |||
<p> | |||
<a | |||
className="button" |
@@ -9,12 +9,19 @@ exports[`renders correctly 1`] = ` | |||
</h4> | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.build_wrapper.text.win", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.build_wrapper.text" | |||
id="onboarding.analysis.build_wrapper.text" | |||
values={ | |||
Object { | |||
"env_var": <code> | |||
%PATH% | |||
</code>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p> | |||
<a | |||
className="button" | |||
@@ -37,12 +44,19 @@ exports[`renders correctly 2`] = ` | |||
</h4> | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.build_wrapper.text.linux", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.build_wrapper.text" | |||
id="onboarding.analysis.build_wrapper.text" | |||
values={ | |||
Object { | |||
"env_var": <code> | |||
PATH | |||
</code>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p> | |||
<a | |||
className="button" | |||
@@ -65,12 +79,19 @@ exports[`renders correctly 3`] = ` | |||
</h4> | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.build_wrapper.text.mac", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.build_wrapper.text" | |||
id="onboarding.analysis.build_wrapper.text" | |||
values={ | |||
Object { | |||
"env_var": <code> | |||
PATH | |||
</code>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p> | |||
<a | |||
className="button" |
@@ -38,12 +38,23 @@ exports[`renders correctly 1`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.sq_scanner.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.sq_scanner.docs" | |||
id="onboarding.analysis.sq_scanner.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.sq_scanner.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
`; | |||
@@ -85,12 +96,23 @@ exports[`renders correctly 2`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.sq_scanner.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.sq_scanner.docs" | |||
id="onboarding.analysis.sq_scanner.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.sq_scanner.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
`; | |||
@@ -133,11 +155,22 @@ exports[`renders correctly 3`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.sq_scanner.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.sq_scanner.docs" | |||
id="onboarding.analysis.sq_scanner.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.sq_scanner.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
`; |
@@ -39,12 +39,23 @@ exports[`renders correctly 1`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.msbuild.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.docs" | |||
id="onboarding.analysis.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.msbuild.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
`; | |||
@@ -88,11 +99,22 @@ exports[`renders correctly 2`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.msbuild.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.docs" | |||
id="onboarding.analysis.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.msbuild.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
`; |
@@ -35,20 +35,28 @@ exports[`renders correctly 1`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.java.gradle.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.docs" | |||
id="onboarding.analysis.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/gradle.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.java.gradle.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.browse_url_after_analysis", | |||
} | |||
} | |||
/> | |||
> | |||
onboarding.analysis.browse_url_after_analysis | |||
</p> | |||
</div> | |||
`; | |||
@@ -87,20 +95,28 @@ exports[`renders correctly 2`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.java.gradle.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.docs" | |||
id="onboarding.analysis.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/gradle.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.java.gradle.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.browse_url_after_analysis", | |||
} | |||
} | |||
/> | |||
> | |||
onboarding.analysis.browse_url_after_analysis | |||
</p> | |||
</div> | |||
`; | |||
@@ -139,19 +155,27 @@ exports[`renders with projectKey 1`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.java.gradle.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.docs" | |||
id="onboarding.analysis.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/gradle.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.java.gradle.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.auto_refresh_after_analysis", | |||
} | |||
} | |||
/> | |||
> | |||
onboarding.analysis.auto_refresh_after_analysis | |||
</p> | |||
</div> | |||
`; |
@@ -27,20 +27,28 @@ exports[`renders correctly 1`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.java.maven.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.docs" | |||
id="onboarding.analysis.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.java.maven.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.browse_url_after_analysis", | |||
} | |||
} | |||
/> | |||
> | |||
onboarding.analysis.browse_url_after_analysis | |||
</p> | |||
</div> | |||
`; | |||
@@ -71,20 +79,28 @@ exports[`renders correctly 2`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.java.maven.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.docs" | |||
id="onboarding.analysis.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.java.maven.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.browse_url_after_analysis", | |||
} | |||
} | |||
/> | |||
> | |||
onboarding.analysis.browse_url_after_analysis | |||
</p> | |||
</div> | |||
`; | |||
@@ -115,19 +131,27 @@ exports[`renders with projectKey 1`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.java.maven.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.docs" | |||
id="onboarding.analysis.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.java.maven.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.auto_refresh_after_analysis", | |||
} | |||
} | |||
/> | |||
> | |||
onboarding.analysis.auto_refresh_after_analysis | |||
</p> | |||
</div> | |||
`; |
@@ -9,12 +9,19 @@ exports[`renders correctly 1`] = ` | |||
</h4> | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.msbuild.text", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.msbuild.text" | |||
id="onboarding.analysis.msbuild.text" | |||
values={ | |||
Object { | |||
"code": <code> | |||
%PATH% | |||
</code>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p> | |||
<a | |||
className="button" |
@@ -43,12 +43,23 @@ exports[`renders correctly 1`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.msbuild.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.docs" | |||
id="onboarding.analysis.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.msbuild.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
`; | |||
@@ -97,11 +108,22 @@ exports[`renders correctly 2`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.msbuild.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.docs" | |||
id="onboarding.analysis.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.msbuild.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
`; |
@@ -30,12 +30,23 @@ exports[`renders correctly 1`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.sq_scanner.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.sq_scanner.docs" | |||
id="onboarding.analysis.sq_scanner.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.sq_scanner.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
`; | |||
@@ -69,12 +80,23 @@ exports[`renders correctly 2`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.sq_scanner.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.sq_scanner.docs" | |||
id="onboarding.analysis.sq_scanner.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.sq_scanner.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
`; | |||
@@ -108,11 +130,22 @@ exports[`renders correctly 3`] = ` | |||
/> | |||
<p | |||
className="big-spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.sq_scanner.docs", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.sq_scanner.docs" | |||
id="onboarding.analysis.sq_scanner.docs" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.analysis.sq_scanner.docs_link | |||
</a>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
</div> | |||
`; |
@@ -9,12 +9,22 @@ exports[`renders correctly 1`] = ` | |||
</h4> | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.sq_scanner.text.win", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.sq_scanner.text" | |||
id="onboarding.analysis.sq_scanner.text" | |||
values={ | |||
Object { | |||
"dir": <code> | |||
bin | |||
</code>, | |||
"env_var": <code> | |||
%PATH% | |||
</code>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p> | |||
<a | |||
className="button" | |||
@@ -37,12 +47,22 @@ exports[`renders correctly 2`] = ` | |||
</h4> | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.sq_scanner.text.linux", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.sq_scanner.text" | |||
id="onboarding.analysis.sq_scanner.text" | |||
values={ | |||
Object { | |||
"dir": <code> | |||
bin | |||
</code>, | |||
"env_var": <code> | |||
PATH | |||
</code>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p> | |||
<a | |||
className="button" | |||
@@ -65,12 +85,22 @@ exports[`renders correctly 3`] = ` | |||
</h4> | |||
<p | |||
className="spacer-bottom markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "onboarding.analysis.sq_scanner.text.mac", | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.analysis.sq_scanner.text" | |||
id="onboarding.analysis.sq_scanner.text" | |||
values={ | |||
Object { | |||
"dir": <code> | |||
bin | |||
</code>, | |||
"env_var": <code> | |||
PATH | |||
</code>, | |||
} | |||
} | |||
} | |||
/> | |||
/> | |||
</p> | |||
<p> | |||
<a | |||
className="button" |
@@ -171,6 +171,7 @@ export default class Action extends React.PureComponent<Props, State> { | |||
<div className="boxed-group-inner"> | |||
<div | |||
className="web-api-action-description markdown" | |||
// Safe: comes from the backend | |||
dangerouslySetInnerHTML={{ __html: action.description }} | |||
/> | |||
@@ -52,6 +52,7 @@ export default function Domain({ domain, query }: Props) { | |||
{domain.description && ( | |||
<div | |||
className="web-api-domain-description markdown" | |||
// Safe: comes from the backend | |||
dangerouslySetInnerHTML={{ __html: domain.description }} | |||
/> | |||
)} |
@@ -99,6 +99,7 @@ export default class Params extends React.PureComponent<Props> { | |||
<td> | |||
<div | |||
className="markdown" | |||
// Safe: comes from the backend | |||
dangerouslySetInnerHTML={{ __html: param.description }} | |||
/> | |||
</td> |
@@ -84,10 +84,6 @@ export default class TreeMapRect extends React.PureComponent<Props> { | |||
const isTextVisible = this.props.width >= 40 && this.props.height >= 45; | |||
const isIconVisible = this.props.width >= 24 && this.props.height >= 26; | |||
const label = this.props.prefix | |||
? `${this.props.prefix}<br>${this.props.label.substr(this.props.prefix.length)}` | |||
: this.props.label; | |||
return ( | |||
<div | |||
className="treemap-cell" | |||
@@ -101,9 +97,16 @@ export default class TreeMapRect extends React.PureComponent<Props> { | |||
{this.props.icon} | |||
</span> | |||
)} | |||
{isTextVisible && ( | |||
<span className="treemap-text" dangerouslySetInnerHTML={{ __html: label }} /> | |||
)} | |||
{isTextVisible && | |||
(this.props.prefix ? ( | |||
<span className="treemap-text"> | |||
{this.props.prefix} | |||
<br /> | |||
{this.props.label.substr(this.props.prefix.length)} | |||
</span> | |||
) : ( | |||
<span className="treemap-text">{this.props.label}</span> | |||
))} | |||
</div> | |||
{this.renderLink()} | |||
</div> |
@@ -18,17 +18,28 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import { mount } from 'enzyme'; | |||
import TreeMap from '../TreeMap'; | |||
import TreeMapRect from '../TreeMapRect'; | |||
import { mockEvent } from '../../../helpers/testMocks'; | |||
it('should display', () => { | |||
it('should render correctly', () => { | |||
const items = [ | |||
{ key: '1', size: 10, color: '#777', label: 'SonarQube :: Server' }, | |||
{ key: '2', size: 30, color: '#777', label: 'SonarQube :: Web' }, | |||
{ key: '3', size: 20, color: '#777', label: 'SonarQube :: Search' } | |||
]; | |||
const chart = shallow( | |||
<TreeMap height={100} items={items} onRectangleClick={() => {}} width={100} /> | |||
const onRectClick = jest.fn(); | |||
const chart = mount( | |||
<TreeMap height={100} items={items} onRectangleClick={onRectClick} width={100} /> | |||
); | |||
expect(chart.find('TreeMapRect')).toHaveLength(3); | |||
const rects = chart.find(TreeMapRect); | |||
expect(rects).toHaveLength(3); | |||
const event: React.MouseEvent<HTMLAnchorElement> = mockEvent({ stopPropagation: jest.fn() }); | |||
(rects.first().instance() as TreeMapRect).handleLinkClick(event); | |||
expect(event.stopPropagation).toHaveBeenCalled(); | |||
(rects.first().instance() as TreeMapRect).handleRectClick(); | |||
expect(onRectClick).toHaveBeenCalledWith('2'); | |||
}); |
@@ -89,6 +89,7 @@ export default class IssueCommentLine extends React.PureComponent<Props, State> | |||
</div> | |||
<div | |||
className="issue-comment-text markdown" | |||
// Safe: Comes from the backend, after markdown transformation to html | |||
dangerouslySetInnerHTML={{ __html: comment.htmlText }} | |||
/> | |||
<div className="issue-comment-age"> |
@@ -619,6 +619,18 @@ export function mockRuleDetails(overrides: Partial<T.RuleDetails> = {}): T.RuleD | |||
}; | |||
} | |||
export function mockRuleDetailsParameter( | |||
overrides: Partial<T.RuleParameter> = {} | |||
): T.RuleParameter { | |||
return { | |||
defaultValue: '1', | |||
htmlDesc: 'description', | |||
key: '1', | |||
type: 'number', | |||
...overrides | |||
}; | |||
} | |||
export function mockShortLivingBranch( | |||
overrides: Partial<T.ShortLivingBranch> = {} | |||
): T.ShortLivingBranch { |
@@ -967,6 +967,23 @@ | |||
"@types/d3-interpolate" "*" | |||
"@types/d3-selection" "*" | |||
"@types/domhandler@*": | |||
version "2.4.1" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/domhandler/-/domhandler-2.4.1.tgz#7b3b347f7762180fbcb1ece1ce3dd0ebbb8c64cf" | |||
integrity sha1-ezs0f3diGA+8sezhzj3Q67uMZM8= | |||
"@types/dompurify@^0.0.32": | |||
version "0.0.32" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/dompurify/-/dompurify-0.0.32.tgz#ccc4148d7f2e0598006611e82e840806fab4b268" | |||
integrity sha1-zMQUjX8uBZgAZhHoLoQIBvq0smg= | |||
"@types/domutils@*": | |||
version "1.7.2" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/domutils/-/domutils-1.7.2.tgz#89422e579c165994ad5c09ce90325da596cc105d" | |||
integrity sha1-iUIuV5wWWZStXAnOkDJdpZbMEF0= | |||
dependencies: | |||
"@types/domhandler" "*" | |||
"@types/enzyme@3.9.1": | |||
version "3.9.1" | |||
resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.9.1.tgz#3a0ce07e30066dbc26cd3474c8e680af2d249e26" | |||
@@ -994,6 +1011,15 @@ | |||
resolved "https://registry.yarnpkg.com/@types/history/-/history-3.2.3.tgz#2416fee5cac641da2d05a905de5af5cb50162f60" | |||
integrity sha512-s4SNWd31cmFP52ilv3LKCh344ayIXmfmcfExsegGspgnk/pQh75Yo6v49uzSE1oFMXp+Sz4GVnesL7rgybX9tQ== | |||
"@types/htmlparser2@*": | |||
version "3.10.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/htmlparser2/-/htmlparser2-3.10.0.tgz#b94d3b08f813c9eec12990ac6a34d8b17a7aebc9" | |||
integrity sha1-uU07CPgTye7BKZCsajTYsXp668k= | |||
dependencies: | |||
"@types/domhandler" "*" | |||
"@types/domutils" "*" | |||
"@types/node" "*" | |||
"@types/istanbul-lib-coverage@^1.1.0": | |||
version "1.1.0" | |||
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz#2cc2ca41051498382b43157c8227fea60363f94a" | |||
@@ -1106,6 +1132,13 @@ | |||
"@types/prop-types" "*" | |||
csstype "^2.2.0" | |||
"@types/sanitize-html@1.20.0": | |||
version "1.20.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/sanitize-html/-/sanitize-html-1.20.0.tgz#b3beaa9eacab0e0fa5022d5faa727fea8fb9fc5d" | |||
integrity sha1-s76qnqyrDg+lAi1fqnJ/6o+5/F0= | |||
dependencies: | |||
"@types/htmlparser2" "*" | |||
"@types/stack-utils@^1.0.1": | |||
version "1.0.1" | |||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" | |||
@@ -3408,6 +3441,11 @@ domhandler@^2.3.0: | |||
dependencies: | |||
domelementtype "1" | |||
dompurify@^1.0.11: | |||
version "1.0.11" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/dompurify/-/dompurify-1.0.11.tgz#fe0f4a40d147f7cebbe31a50a1357539cfc1eb4d" | |||
integrity sha1-/g9KQNFH98674xpQoTV1Oc/B600= | |||
domutils@1.5.1: | |||
version "1.5.1" | |||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" |
@@ -936,6 +936,13 @@ property.error.notRegexp=Not a valid Java regular expression | |||
property.error.notInOptions=Not a valid option | |||
property.category.scm=SCM | |||
property.sonar.leak.period.description=Period used to compare measures and track new issues. Values are:<ul class='bullet'><li>Number of days before analysis, for example 5.</li><li>A custom date. Format is yyyy-MM-dd, for example 2010-12-25</li><li>'previous_version' to compare to the previous version in the project history</li><li>A version, for example '1.2' or 'BASELINE'</li></ul><p>When specifying a number of days or a date, the snapshot selected as the baseline for comparison is the first one available inside the corresponding time range. Specifically, the first analysis in the range is considered to be before the New Code Period. </p><p>Changing this property only takes effect after subsequent project analyses.<p/> | |||
property.sonar.leak.period.description.intro=Period used to compare measures and track new issues. Values are: | |||
property.sonar.leak.period.description.item1=Number of days before analysis, for example 5. | |||
property.sonar.leak.period.description.item2=A custom date. Format is yyyy-MM-dd, for example 2010-12-25 | |||
property.sonar.leak.period.description.item3='previous_version' to compare to the previous version in the project history | |||
property.sonar.leak.period.description.item4=A version, for example '1.2' or 'BASELINE' | |||
property.sonar.leak.period.description.details1=When specifying a number of days or a date, the snapshot selected as the baseline for comparison is the first one available inside the corresponding time range. Specifically, the first analysis in the range is considered to be before the New Code Period. | |||
property.sonar.leak.period.description.details2=Changing this property only takes effect after subsequent project analyses. | |||
property.sonar.branch.longLivedBranches.regex.description=Regular expression used to detect whether a branch is a long living branch (as opposed to short living branch), based on its name. This applies only during first analysis, the type of a branch cannot be changed later. | |||
@@ -945,7 +952,7 @@ property.sonar.branch.longLivedBranches.regex.description=Regular expression use | |||
# | |||
#------------------------------------------------------------------------------ | |||
search.shortcut_hint=Hint: Press {shortcut} from anywhere to open this search bar. | |||
search.show_more.hint=Press {0} to display | |||
search.show_more.hint=Press {key} to display | |||
search.placeholder=Search for projects and files... | |||
search.search_for_projects=Search for projects... | |||
search.search_for_users=Search for users... | |||
@@ -2938,37 +2945,36 @@ onboarding.language.os.win=Windows | |||
onboarding.language.os.mac=macOS | |||
onboarding.language.project_key=Define a unique project key | |||
onboarding.analysis.docs=Please visit the {link} for more details. | |||
onboarding.analysis.java.maven.header=Execute the Scanner for Maven from your computer | |||
onboarding.analysis.java.maven.text=Running a {instance} analysis with Maven is straighforward. You just need to run the following command in your project's folder. | |||
onboarding.analysis.java.maven.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html" target="_blank">official documentation of the Scanner for Maven</a> for more details. | |||
onboarding.analysis.java.maven.docs_link=official documentation of the Scanner for Maven | |||
onboarding.analysis.java.gradle.header=Execute the Scanner for Gradle from your computer | |||
onboarding.analysis.java.gradle.text.1=Running an analysis with Gradle is straighforward. You just need to declare the <code>org.sonarqube</code> plugin in your <code>build.gradle</code> file: | |||
onboarding.analysis.java.gradle.text.1=Running an analysis with Gradle is straighforward. You just need to declare the {plugin_code} plugin in your {filename} file: | |||
onboarding.analysis.java.gradle.text.2=and run the following command: | |||
onboarding.analysis.java.gradle.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/gradle.html" target="_blank">official documentation of the Scanner for Gradle</a> for more details. | |||
onboarding.analysis.java.gradle.docs_link=official documentation of the Scanner for Gradle | |||
onboarding.analysis.msbuild.header=Download and unzip the Scanner for MSBuild | |||
onboarding.analysis.msbuild.text=And add the executable's directory to the <code>%PATH%</code> environment variable | |||
onboarding.analysis.msbuild.text=And add the executable's directory to the {code} environment variable | |||
onboarding.analysis.msbuild.execute=Execute the Scanner for MSBuild from your computer | |||
onboarding.analysis.msbuild.execute.text=Running a {instance} analysis is straighforward. You just need to execute the following commands at the root of your solution. | |||
onboarding.analysis.msbuild.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html" target="_blank">official documentation of the Scanner for MSBuild</a> for more details. | |||
onboarding.analysis.msbuild.docs_link=official documentation of the Scanner for MSBuild | |||
onboarding.analysis.build_wrapper.header.linux=Download and unzip the Build Wrapper for Linux | |||
onboarding.analysis.build_wrapper.header.win=Download and unzip the Build Wrapper for Windows | |||
onboarding.analysis.build_wrapper.header.mac=Download and unzip the Build Wrapper for macOS | |||
onboarding.analysis.build_wrapper.text.linux=And add the executable's directory to the <code>PATH</code> environment variable | |||
onboarding.analysis.build_wrapper.text.win=And add the executable's directory to the <code>%PATH%</code> environment variable | |||
onboarding.analysis.build_wrapper.text.mac=And add the executable's directory to the <code>PATH</code> environment variable | |||
onboarding.analysis.build_wrapper.text=And add the executable's directory to the {env_var} environment variable | |||
onboarding.analysis.sq_scanner.header.linux=Download and unzip the Scanner for Linux | |||
onboarding.analysis.sq_scanner.header.win=Download and unzip the Scanner for Windows | |||
onboarding.analysis.sq_scanner.header.mac=Download and unzip the Scanner for macOS | |||
onboarding.analysis.sq_scanner.text.linux=And add the <code>bin</code> directory to the <code>PATH</code> environment variable | |||
onboarding.analysis.sq_scanner.text.win=And add the <code>bin</code> directory to the <code>%PATH%</code> environment variable | |||
onboarding.analysis.sq_scanner.text.mac=And add the <code>bin</code> directory to the <code>PATH</code> environment variable | |||
onboarding.analysis.sq_scanner.text=And add the {dir} directory to the {env_var} environment variable | |||
onboarding.analysis.sq_scanner.execute=Execute the Scanner from your computer | |||
onboarding.analysis.sq_scanner.execute.text=Running a {instance} analysis is straighforward. You just need to execute the following commands in your project's folder. | |||
onboarding.analysis.sq_scanner.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" target="_blank">official documentation of the Scanner</a> for more details. | |||
onboarding.analysis.sq_scanner.docs=Please visit the {link} for more details. | |||
onboarding.analysis.sq_scanner.docs_link=official documentation of the Scanner | |||
onboarding.project_watcher.not_started=Once your project is analyzed, this page will refresh automatically. | |||
onboarding.project_watcher.in_progress=Analysis is in progress, please wait... | |||
@@ -3062,8 +3068,10 @@ encryption.encrypt=Encrypt | |||
encryption.secret_key_description=Secret key is required to be able to encrypt properties. {moreInformationLink} | |||
encryption.secret_key=Secret Key | |||
encryption.how_to_use=How To Use | |||
encryption.how_to_use.content=<ul><li>Store the secret key in the file <code>~/.sonar/sonar-secret.txt</code> of the server. This file can be relocated by defining the property <code>sonar.secretKeyPath</code> in <code>conf/sonar.properties</code></li><li>Restrict access to this file by making it readable and by owner only</li><li>Restart the server if the property <code>sonar.secretKeyPath</code> has been set or changed.</li><li>For each property that you want to encrypt, generate the encrypted value and replace the original value wherever it is stored (configuration files, command lines).</li></ul> | |||
encryption.how_to_use.content1=Store the secret key in the file {secret_file} of the server. This file can be relocated by defining the property {property} in {propreties_file} | |||
encryption.how_to_use.content2=Restrict access to this file by making it readable and by owner only | |||
encryption.how_to_use.content3=Restart the server if the property {property} has been set or changed. | |||
encryption.how_to_use.content4=For each property that you want to encrypt, generate the encrypted value and replace the original value wherever it is stored (configuration files, command lines). | |||
#------------------------------------------------------------------------------ | |||
# | |||
@@ -3152,8 +3160,10 @@ maintenance.is_down={instance} is down | |||
maintenance.sonarqube_is_down.text=Something went wrong. Please contact your system administrator. | |||
maintenance.try_again=Try Again | |||
maintenance.is_under_maintenance={instance} is under maintenance | |||
maintenance.sonarqube_is_under_maintenance.1=While waiting, you might want to investigate <a href="https://redirect.sonarsource.com/doc/plugin-library.html">new plugins</a> to extend the current functionality. | |||
maintenance.sonarqube_is_under_maintenance.2=If you are an administrator and have no idea why this message is being shown, you should read the <a href="https://redirect.sonarsource.com/doc/upgrading.html">upgrade guide</a>. | |||
maintenance.sonarqube_is_under_maintenance.1=While waiting, you might want to investigate {link} to extend the current functionality. | |||
maintenance.sonarqube_is_under_maintenance_link.1=new plugins | |||
maintenance.sonarqube_is_under_maintenance.2=If you are an administrator and have no idea why this message is being shown, you should read the {link}. | |||
maintenance.sonarqube_is_under_maintenance_link.2=upgrade guide | |||
maintenance.is_starting={instance} is starting | |||
maintenance.is_up={instance} is up | |||
maintenance.all_systems_opetational=All systems operational. |