* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { Link } from 'react-router';
import { ButtonLink } from '../../../../components/controls/buttons';
+import { Alert } from '../../../../components/ui/Alert';
import MandatoryFieldMarker from '../../../../components/ui/MandatoryFieldMarker';
import { translate } from '../../../../helpers/l10n';
import { AlmBindingDefinitionBase } from '../../../../types/alm-settings';
overwriteOnly?: boolean;
propKey: keyof B;
value: string;
+ isSecret?: boolean;
}
export function AlmBindingDefinitionFormField<B extends AlmBindingDefinitionBase>(
optional,
overwriteOnly = false,
propKey,
- value
+ value,
+ isSecret
} = props;
const [showField, setShowField] = React.useState(!overwriteOnly);
{!optional && <MandatoryFieldMarker />}
{help && <div className="markdown small spacer-top">{help}</div>}
</div>
- <div className="settings-definition-right big-padded-top">
+ <div className="settings-definition-right big-padded-top display-flex-column">
{!showField && overwriteOnly && (
<div>
- <p>{translate('settings.almintegration.form.secret_field')}</p>
+ <p>{translate('settings.almintegration.form.secret.field')}</p>
<ButtonLink
onClick={() => {
props.onFieldChange(propKey, '');
setShowField(true);
}}>
- {translate('settings.almintegration.form.update_secret_field')}
+ {translate('settings.almintegration.form.secret.update_field')}
</ButtonLink>
</div>
)}
{showField && isTextArea && (
<textarea
- className="settings-large-input"
+ className="width-100"
id={id}
maxLength={maxLength || 2000}
onChange={e => props.onFieldChange(propKey, e.currentTarget.value)}
{showField && !isTextArea && (
<input
+ className="width-100"
autoFocus={autoFocus}
- className="settings-large-input"
id={id}
maxLength={maxLength || 100}
name={id}
value={value}
/>
)}
+
+ {showField && isSecret && (
+ <Alert variant="info" className="spacer-top">
+ <FormattedMessage
+ id="settings.almintegration.form.secret.can_encrypt"
+ defaultMessage={translate('settings.almintegration.form.secret.can_encrypt')}
+ values={{
+ learn_more: (
+ <Link
+ target="_blank"
+ to={{
+ pathname:
+ '/documentation/instance-administration/security/#settings-encryption'
+ }}>
+ {translate('learn_more')}
+ </Link>
+ )
+ }}
+ />
+ </Alert>
+ )}
</div>
</div>
);
overwriteOnly={Boolean(formData.key)}
propKey="personalAccessToken"
value={formData.personalAccessToken}
+ isSecret={true}
/>
</>
);
propKey="workspace"
value={formData.workspace || ''}
/>
- <Alert className="big-spacer-top big-spacer-right" variant="info">
+ <Alert className="big-spacer-top" variant="info">
<FormattedMessage
defaultMessage={translate(`settings.almintegration.bitbucketcloud.info`)}
id="settings.almintegration.bitbucketcloud.info"
overwriteOnly={Boolean(formData.key)}
propKey="clientSecret"
value={formData.clientSecret || ''}
+ isSecret={true}
/>
</>
);
overwriteOnly={Boolean(formData.key)}
propKey="personalAccessToken"
value={formData.personalAccessToken || ''}
+ isSecret={true}
/>
</>
);
propKey="url"
value={formData.url}
/>
- <Alert className="big-spacer-top big-spacer-right" variant="info">
+ <Alert className="big-spacer-top" variant="info">
<FormattedMessage
defaultMessage={translate(`settings.almintegration.github.info`)}
id="settings.almintegration.github.info"
overwriteOnly={Boolean(formData.key)}
propKey="clientSecret"
value={formData.clientSecret}
+ isSecret={true}
/>
<AlmBindingDefinitionFormField
id="private_key"
overwriteOnly={Boolean(formData.key)}
propKey="privateKey"
value={formData.privateKey}
+ isSecret={true}
/>
</>
);
overwriteOnly={Boolean(formData.key)}
propKey="personalAccessToken"
value={formData.personalAccessToken}
+ isSecret={true}
/>
</>
);
expect(shallowRender({ isTextArea: true })).toMatchSnapshot('textarea');
expect(shallowRender({ optional: true })).toMatchSnapshot('optional');
expect(shallowRender({ overwriteOnly: true })).toMatchSnapshot('secret');
+ expect(shallowRender({ isSecret: true })).toMatchSnapshot('encryptable');
});
it('should call onFieldChange', () => {
<MandatoryFieldMarker />
</div>
<div
- className="settings-definition-right big-padded-top"
+ className="settings-definition-right big-padded-top display-flex-column"
>
<input
- className="settings-large-input"
+ className="width-100"
id="key"
maxLength={40}
name="key"
</div>
`;
+exports[`should render correctly: encryptable 1`] = `
+<div
+ className="settings-definition"
+>
+ <div
+ className="settings-definition-left"
+ >
+ <label
+ className="h3"
+ htmlFor="key"
+ >
+ settings.almintegration.form.key
+ </label>
+ <MandatoryFieldMarker />
+ </div>
+ <div
+ className="settings-definition-right big-padded-top display-flex-column"
+ >
+ <input
+ className="width-100"
+ id="key"
+ maxLength={40}
+ name="key"
+ onChange={[Function]}
+ size={50}
+ type="text"
+ value="key"
+ />
+ <Alert
+ className="spacer-top"
+ variant="info"
+ >
+ <FormattedMessage
+ defaultMessage="settings.almintegration.form.secret.can_encrypt"
+ id="settings.almintegration.form.secret.can_encrypt"
+ values={
+ Object {
+ "learn_more": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to={
+ Object {
+ "pathname": "/documentation/instance-administration/security/#settings-encryption",
+ }
+ }
+ >
+ learn_more
+ </Link>,
+ }
+ }
+ />
+ </Alert>
+ </div>
+</div>
+`;
+
exports[`should render correctly: optional 1`] = `
<div
className="settings-definition"
</label>
</div>
<div
- className="settings-definition-right big-padded-top"
+ className="settings-definition-right big-padded-top display-flex-column"
>
<input
- className="settings-large-input"
+ className="width-100"
id="key"
maxLength={40}
name="key"
<MandatoryFieldMarker />
</div>
<div
- className="settings-definition-right big-padded-top"
+ className="settings-definition-right big-padded-top display-flex-column"
>
<div>
<p>
- settings.almintegration.form.secret_field
+ settings.almintegration.form.secret.field
</p>
<ButtonLink
onClick={[Function]}
>
- settings.almintegration.form.update_secret_field
+ settings.almintegration.form.secret.update_field
</ButtonLink>
</div>
</div>
<MandatoryFieldMarker />
</div>
<div
- className="settings-definition-right big-padded-top"
+ className="settings-definition-right big-padded-top display-flex-column"
>
<textarea
- className="settings-large-input"
+ className="width-100"
id="key"
maxLength={40}
onChange={[Function]}
</div>
</div>
<div
- className="settings-definition-right big-padded-top"
+ className="settings-definition-right big-padded-top display-flex-column"
>
<input
- className="settings-large-input"
+ className="width-100"
id="key"
maxLength={40}
name="key"
/>
}
id="personal_access_token"
+ isSecret={true}
isTextArea={true}
onFieldChange={[MockFunction]}
overwriteOnly={false}
/>
}
id="personal_access_token"
+ isSecret={true}
isTextArea={true}
onFieldChange={[MockFunction]}
overwriteOnly={true}
value="workspace"
/>
<Alert
- className="big-spacer-top big-spacer-right"
+ className="big-spacer-top"
variant="info"
>
<FormattedMessage
<AlmBindingDefinitionFormField
help="settings.almintegration.form.oauth_secret.bitbucketcloud.help"
id="client_secret.bitbucketcloud"
+ isSecret={true}
onFieldChange={[MockFunction]}
overwriteOnly={true}
propKey="clientSecret"
/>
}
id="personal_access_token"
+ isSecret={true}
isTextArea={true}
onFieldChange={[MockFunction]}
overwriteOnly={true}
value=""
/>
<Alert
- className="big-spacer-top big-spacer-right"
+ className="big-spacer-top"
variant="info"
>
<FormattedMessage
<AlmBindingDefinitionFormField
help="settings.almintegration.form.client_secret.github.help"
id="client_secret.github"
+ isSecret={true}
maxLength={80}
onFieldChange={[MockFunction]}
overwriteOnly={false}
<AlmBindingDefinitionFormField
help="settings.almintegration.form.private_key.github.help"
id="private_key"
+ isSecret={true}
isTextArea={true}
onFieldChange={[MockFunction]}
overwriteOnly={false}
value="http://github.enterprise.com"
/>
<Alert
- className="big-spacer-top big-spacer-right"
+ className="big-spacer-top"
variant="info"
>
<FormattedMessage
<AlmBindingDefinitionFormField
help="settings.almintegration.form.client_secret.github.help"
id="client_secret.github"
+ isSecret={true}
maxLength={80}
onFieldChange={[MockFunction]}
overwriteOnly={true}
<AlmBindingDefinitionFormField
help="settings.almintegration.form.private_key.github.help"
id="private_key"
+ isSecret={true}
isTextArea={true}
onFieldChange={[MockFunction]}
overwriteOnly={true}
/>
}
id="personal_access_token"
+ isSecret={true}
isTextArea={true}
onFieldChange={[MockFunction]}
overwriteOnly={false}
/>
}
id="personal_access_token"
+ isSecret={true}
isTextArea={true}
onFieldChange={[MockFunction]}
overwriteOnly={true}
settings.almintegration.form.client_secret.bitbucketcloud=OAuth Secret
settings.almintegration.form.private_key=Private Key
settings.almintegration.form.private_key.github.help=Your GitHub App's private key. You can generate a .pem file from your GitHub App's page under Private keys. Copy and paste the whole contents of the file here.
-settings.almintegration.form.personal_access_token=Personal Access token
+settings.almintegration.form.personal_access_token=Personal Access Token
settings.almintegration.form.personal_access_token.azure.help=SonarQube needs a {pat} to report the Quality Gate status on Pull Requests in Azure DevOps. To create this token, we recommend using a dedicated Azure DevOps account with administration permissions. The token itself needs {permission} permission. {doc_link}
settings.almintegration.form.personal_access_token.azure.help.url=Personal Access Token
settings.almintegration.form.personal_access_token.gitlab.help=SonarQube needs a {pat} to report the Quality Gate status on Merge Requests in GitLab. To create this token, we recommend using a dedicated GitLab account with {permission} permission to all target projects. The token itself needs the {scope} scope. {doc_link}
settings.almintegration.form.personal_access_token.bitbucket.help.url=Personal Access Token
settings.almintegration.form.save=Save configuration
settings.almintegration.form.cancel=Cancel
-settings.almintegration.form.secret_field=This field is hidden for security reasons.
-settings.almintegration.form.update_secret_field=Update field value
+settings.almintegration.form.secret.field=This field is hidden for security reasons.
+settings.almintegration.form.secret.update_field=Update field value
+settings.almintegration.form.secret.can_encrypt=You can encrypt this value. {learn_more}
settings.almintegration.feature.status_reporting.title=Quality Gate status reporting
settings.almintegration.feature.status_reporting.description_pr=Add analysis and a Quality Gate to your Pull Requests directly in your ALM provider's interface.
settings.almintegration.feature.status_reporting.description_pr_and_commits=Add the Quality Gate status to your Pull Requests and on analyzed commits directly in your ALM provider's interface.