Kaynağa Gözat

SONAR-12196 Fix SSF-79

tags/8.0
Jeremy Davis 5 yıl önce
ebeveyn
işleme
d835fdaa1d
48 değiştirilmiş dosya ile 1022 ekleme ve 325 silme
  1. 5
    1
      server/sonar-docs/src/templates/page.tsx
  2. 3
    0
      server/sonar-web/package.json
  3. 1
    0
      server/sonar-web/src/main/js/app/components/search/SearchResult.tsx
  4. 11
    10
      server/sonar-web/src/main/js/app/components/search/SearchShowMore.tsx
  5. 14
    5
      server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchShowMore-test.tsx.snap
  6. 5
    1
      server/sonar-web/src/main/js/apps/about/components/AboutApp.tsx
  7. 1
    0
      server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx
  8. 1
    0
      server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx
  9. 2
    0
      server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx
  10. 3
    1
      server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsParameters.tsx
  11. 33
    0
      server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/RuleDetailsParameters-test.tsx
  12. 83
    0
      server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleDetailsParameters-test.tsx.snap
  13. 1
    0
      server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.tsx
  14. 28
    13
      server/sonar-web/src/main/js/apps/maintenance/components/App.tsx
  15. 56
    20
      server/sonar-web/src/main/js/apps/maintenance/components/__tests__/__snapshots__/App-test.tsx.snap
  16. 4
    1
      server/sonar-web/src/main/js/apps/projectBranches/components/SettingForm.tsx
  17. 104
    1
      server/sonar-web/src/main/js/apps/settings/__tests__/utils-test.ts
  18. 3
    2
      server/sonar-web/src/main/js/apps/settings/components/Definition.tsx
  19. 2
    2
      server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx
  20. 26
    4
      server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.tsx
  21. 7
    0
      server/sonar-web/src/main/js/apps/settings/utils.ts
  22. 10
    6
      server/sonar-web/src/main/js/apps/tutorials/components/commands/BuildWrapper.tsx
  23. 18
    10
      server/sonar-web/src/main/js/apps/tutorials/components/commands/ClangGCC.tsx
  24. 18
    10
      server/sonar-web/src/main/js/apps/tutorials/components/commands/DotNet.tsx
  25. 32
    16
      server/sonar-web/src/main/js/apps/tutorials/components/commands/JavaGradle.tsx
  26. 22
    12
      server/sonar-web/src/main/js/apps/tutorials/components/commands/JavaMaven.tsx
  27. 8
    4
      server/sonar-web/src/main/js/apps/tutorials/components/commands/MSBuildScanner.tsx
  28. 18
    10
      server/sonar-web/src/main/js/apps/tutorials/components/commands/Msvc.tsx
  29. 18
    10
      server/sonar-web/src/main/js/apps/tutorials/components/commands/Other.tsx
  30. 11
    6
      server/sonar-web/src/main/js/apps/tutorials/components/commands/SQScanner.tsx
  31. 36
    15
      server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/BuildWrapper-test.tsx.snap
  32. 48
    15
      server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/ClangGCC-test.tsx.snap
  33. 32
    10
      server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/DotNet-test.tsx.snap
  34. 57
    33
      server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/JavaGradle-test.tsx.snap
  35. 57
    33
      server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/JavaMaven-test.tsx.snap
  36. 12
    5
      server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/MSBuildScanner-test.tsx.snap
  37. 32
    10
      server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/Msvc-test.tsx.snap
  38. 48
    15
      server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/Other-test.tsx.snap
  39. 45
    15
      server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/SQScanner-test.tsx.snap
  40. 1
    0
      server/sonar-web/src/main/js/apps/web-api/components/Action.tsx
  41. 1
    0
      server/sonar-web/src/main/js/apps/web-api/components/Domain.tsx
  42. 1
    0
      server/sonar-web/src/main/js/apps/web-api/components/Params.tsx
  43. 10
    7
      server/sonar-web/src/main/js/components/charts/TreeMapRect.tsx
  44. 16
    5
      server/sonar-web/src/main/js/components/charts/__tests__/TreeMap-test.tsx
  45. 1
    0
      server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.tsx
  46. 12
    0
      server/sonar-web/src/main/js/helpers/testMocks.ts
  47. 38
    0
      server/sonar-web/yarn.lock
  48. 27
    17
      sonar-core/src/main/resources/org/sonar/l10n/core.properties

+ 5
- 1
server/sonar-docs/src/templates/page.tsx Dosyayı Görüntüle

@@ -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 }}
/>
</>
);
}

+ 3
- 0
server/sonar-web/package.json Dosyayı Görüntüle

@@ -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",

+ 1
- 0
server/sonar-web/src/main/js/app/components/search/SearchResult.tsx Dosyayı Görüntüle

@@ -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 }}
/>
) : (

+ 11
- 10
server/sonar-web/src/main/js/app/components/search/SearchShowMore.tsx Dosyayı Görüntüle

@@ -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>

+ 14
- 5
server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchShowMore-test.tsx.snap Dosyayı Görüntüle

@@ -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>

+ 5
- 1
server/sonar-web/src/main/js/apps/about/components/AboutApp.tsx Dosyayı Görüntüle

@@ -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 />

+ 1
- 0
server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx Dosyayı Görüntüle

@@ -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>

+ 1
- 0
server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx Dosyayı Görüntüle

@@ -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>

+ 2
- 0
server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx Dosyayı Görüntüle

@@ -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 || '' }}
/>
) : (

+ 3
- 1
server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsParameters.tsx Dosyayı Görüntüle

@@ -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')}

+ 33
- 0
server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/RuleDetailsParameters-test.tsx Dosyayı Görüntüle

@@ -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} />);
}

+ 83
- 0
server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleDetailsParameters-test.tsx.snap Dosyayı Görüntüle

@@ -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>
`;

+ 1
- 0
server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.tsx Dosyayı Görüntüle

@@ -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

+ 28
- 13
server/sonar-web/src/main/js/apps/maintenance/components/App.tsx Dosyayı Görüntüle

@@ -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>
</>
)}
</>

+ 56
- 20
server/sonar-web/src/main/js/apps/maintenance/components/__tests__/__snapshots__/App-test.tsx.snap Dosyayı Görüntüle

@@ -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>

+ 4
- 1
server/sonar-web/src/main/js/apps/projectBranches/components/SettingForm.tsx Dosyayı Görüntüle

@@ -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

+ 104
- 1
server/sonar-web/src/main/js/apps/settings/__tests__/utils-test.ts Dosyayı Görüntüle

@@ -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 &amp; HtmlParser</title>
<link rel=stylesheet type="text/css" src=foo/bar.css />
<body
bgcolor=white
linkcolor = "blue"
onload="document.writeln(
&quot;&lt;p&gt;properly escaped code in a handler&lt;/p&gt;&quot;);"
>
<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("&lt;b&gt;hi&lt;/b&gt;");</gxp:attr>
</input>
<pre>&lt;div id=notarealtag onclick=notcode()&gt;</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("&lt;b&gt;hi&lt;/b&gt;");&lt;divid=notarealtagonclick=notcode()&gt;&lt;notatag&lt;&lt;&lt;allinonetextblock&gt;&gt;&gt;Makesurethat&lt;%#somephpcodeherewrite("$horriblySyntacticConstruct1");%&gt;*/alert('hi');*/alert('hi');--&gt;*/alert('hi');--&gt;'}--&gt;--&gt;&lt;!--Zoicks--&gt;sectioninHTML]]&gt;Bar`
);
});
});

+ 3
- 2
server/sonar-web/src/main/js/apps/settings/components/Definition.tsx Dosyayı Görüntüle

@@ -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) }}
/>
)}


+ 2
- 2
server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx Dosyayı Görüntüle

@@ -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

+ 26
- 4
server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.tsx Dosyayı Görüntüle

@@ -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}>

+ 7
- 0
server/sonar-web/src/main/js/apps/settings/utils.ts Dosyayı Görüntüle

@@ -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;

+ 10
- 6
server/sonar-web/src/main/js/apps/tutorials/components/commands/BuildWrapper.tsx Dosyayı Görüntüle

@@ -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
- 10
server/sonar-web/src/main/js/apps/tutorials/components/commands/ClangGCC.tsx Dosyayı Görüntüle

@@ -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
- 10
server/sonar-web/src/main/js/apps/tutorials/components/commands/DotNet.tsx Dosyayı Görüntüle

@@ -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>
);
}

+ 32
- 16
server/sonar-web/src/main/js/apps/tutorials/components/commands/JavaGradle.tsx Dosyayı Görüntüle

@@ -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>
);
}

+ 22
- 12
server/sonar-web/src/main/js/apps/tutorials/components/commands/JavaMaven.tsx Dosyayı Görüntüle

@@ -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>
);
}

+ 8
- 4
server/sonar-web/src/main/js/apps/tutorials/components/commands/MSBuildScanner.tsx Dosyayı Görüntüle

@@ -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
- 10
server/sonar-web/src/main/js/apps/tutorials/components/commands/Msvc.tsx Dosyayı Görüntüle

@@ -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
- 10
server/sonar-web/src/main/js/apps/tutorials/components/commands/Other.tsx Dosyayı Görüntüle

@@ -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>
);
}

+ 11
- 6
server/sonar-web/src/main/js/apps/tutorials/components/commands/SQScanner.tsx Dosyayı Görüntüle

@@ -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"

+ 36
- 15
server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/BuildWrapper-test.tsx.snap Dosyayı Görüntüle

@@ -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"

+ 48
- 15
server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/ClangGCC-test.tsx.snap Dosyayı Görüntüle

@@ -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>
`;

+ 32
- 10
server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/DotNet-test.tsx.snap Dosyayı Görüntüle

@@ -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>
`;

+ 57
- 33
server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/JavaGradle-test.tsx.snap Dosyayı Görüntüle

@@ -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>
`;

+ 57
- 33
server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/JavaMaven-test.tsx.snap Dosyayı Görüntüle

@@ -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>
`;

+ 12
- 5
server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/MSBuildScanner-test.tsx.snap Dosyayı Görüntüle

@@ -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"

+ 32
- 10
server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/Msvc-test.tsx.snap Dosyayı Görüntüle

@@ -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>
`;

+ 48
- 15
server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/Other-test.tsx.snap Dosyayı Görüntüle

@@ -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>
`;

+ 45
- 15
server/sonar-web/src/main/js/apps/tutorials/components/commands/__tests__/__snapshots__/SQScanner-test.tsx.snap Dosyayı Görüntüle

@@ -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"

+ 1
- 0
server/sonar-web/src/main/js/apps/web-api/components/Action.tsx Dosyayı Görüntüle

@@ -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 }}
/>


+ 1
- 0
server/sonar-web/src/main/js/apps/web-api/components/Domain.tsx Dosyayı Görüntüle

@@ -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 }}
/>
)}

+ 1
- 0
server/sonar-web/src/main/js/apps/web-api/components/Params.tsx Dosyayı Görüntüle

@@ -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>

+ 10
- 7
server/sonar-web/src/main/js/components/charts/TreeMapRect.tsx Dosyayı Görüntüle

@@ -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>

+ 16
- 5
server/sonar-web/src/main/js/components/charts/__tests__/TreeMap-test.tsx Dosyayı Görüntüle

@@ -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');
});

+ 1
- 0
server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.tsx Dosyayı Görüntüle

@@ -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">

+ 12
- 0
server/sonar-web/src/main/js/helpers/testMocks.ts Dosyayı Görüntüle

@@ -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 {

+ 38
- 0
server/sonar-web/yarn.lock Dosyayı Görüntüle

@@ -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"

+ 27
- 17
sonar-core/src/main/resources/org/sonar/l10n/core.properties Dosyayı Görüntüle

@@ -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.

Loading…
İptal
Kaydet