Commit ec218553 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '280559-remove-dast-site-profile-validation' into 'master'

Remove validation from DAST site profile form

See merge request gitlab-org/gitlab!47701
parents f0b673bc d9cfd07d
<script> <script>
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { import { GlAlert, GlButton, GlForm, GlFormGroup, GlFormInput, GlModal } from '@gitlab/ui';
GlAlert,
GlButton,
GlCollapse,
GlForm,
GlFormGroup,
GlFormInput,
GlModal,
GlToggle,
} from '@gitlab/ui';
import { initFormField } from 'ee/security_configuration/utils'; import { initFormField } from 'ee/security_configuration/utils';
import * as Sentry from '~/sentry/wrapper'; import * as Sentry from '~/sentry/wrapper';
import { __, s__ } from '~/locale'; import { __, s__ } from '~/locale';
import { redirectTo } from '~/lib/utils/url_utility'; import { redirectTo } from '~/lib/utils/url_utility';
import { serializeFormObject } from '~/lib/utils/forms'; import { serializeFormObject } from '~/lib/utils/forms';
import { fetchPolicies } from '~/lib/graphql';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import validation from '~/vue_shared/directives/validation'; import validation from '~/vue_shared/directives/validation';
import DastSiteValidation from './dast_site_validation.vue';
import dastSiteProfileCreateMutation from '../graphql/dast_site_profile_create.mutation.graphql'; import dastSiteProfileCreateMutation from '../graphql/dast_site_profile_create.mutation.graphql';
import dastSiteProfileUpdateMutation from '../graphql/dast_site_profile_update.mutation.graphql'; import dastSiteProfileUpdateMutation from '../graphql/dast_site_profile_update.mutation.graphql';
import dastSiteTokenCreateMutation from '../graphql/dast_site_token_create.mutation.graphql';
import dastSiteValidationQuery from '../graphql/dast_site_validation.query.graphql';
import { DAST_SITE_VALIDATION_STATUS, DAST_SITE_VALIDATION_POLL_INTERVAL } from '../constants';
const { PENDING, INPROGRESS, PASSED, FAILED } = DAST_SITE_VALIDATION_STATUS;
export default { export default {
name: 'DastSiteProfileForm', name: 'DastSiteProfileForm',
components: { components: {
GlAlert, GlAlert,
GlButton, GlButton,
GlCollapse,
GlForm, GlForm,
GlFormGroup, GlFormGroup,
GlFormInput, GlFormInput,
GlModal, GlModal,
GlToggle,
DastSiteValidation,
}, },
directives: { directives: {
validation: validation(), validation: validation(),
}, },
mixins: [glFeatureFlagsMixin()],
props: { props: {
fullPath: { fullPath: {
type: String, type: String,
...@@ -72,18 +51,12 @@ export default { ...@@ -72,18 +51,12 @@ export default {
}; };
return { return {
fetchValidationTimeout: null,
form, form,
initialFormValues: serializeFormObject(form.fields), initialFormValues: serializeFormObject(form.fields),
isFetchingValidationStatus: false,
isValidatingSite: false,
isLoading: false, isLoading: false,
hasAlert: false, hasAlert: false,
tokenId: null, tokenId: null,
token: null, token: null,
isSiteValidationActive: false,
isSiteValidationTouched: false,
validationStatus: null,
errorMessage: '', errorMessage: '',
errors: [], errors: [],
}; };
...@@ -92,9 +65,6 @@ export default { ...@@ -92,9 +65,6 @@ export default {
isEdit() { isEdit() {
return Boolean(this.siteProfile?.id); return Boolean(this.siteProfile?.id);
}, },
isSiteValidationDisabled() {
return !this.form.fields.targetUrl.state || this.validationStatusMatches(INPROGRESS);
},
i18n() { i18n() {
const { isEdit } = this; const { isEdit } = this;
return { return {
...@@ -111,163 +81,18 @@ export default { ...@@ -111,163 +81,18 @@ export default {
okTitle: __('Discard'), okTitle: __('Discard'),
cancelTitle: __('Cancel'), cancelTitle: __('Cancel'),
}, },
siteValidation: {
validationStatusFetchError: s__(
'DastProfiles|Could not retrieve site validation status. Please refresh the page, or try again later.',
),
createTokenError: s__(
'DastProfiles|Could not create site validation token. Please refresh the page, or try again later.',
),
},
}; };
}, },
formTouched() { formTouched() {
return !isEqual(serializeFormObject(this.form.fields), this.initialFormValues); return !isEqual(serializeFormObject(this.form.fields), this.initialFormValues);
}, },
isSubmitDisabled() {
return (
this.validationStatusMatches(INPROGRESS) ||
(this.isSiteValidationActive && !this.validationStatusMatches(PASSED))
);
},
showValidationSection() {
return (
this.isSiteValidationActive &&
!this.isValidatingSite &&
![INPROGRESS, PASSED].some(this.validationStatusMatches)
);
},
siteValidationStatusDescription() {
const descriptions = {
[PENDING]: { text: s__('DastProfiles|Site must be validated to run an active scan.') },
[INPROGRESS]: {
text: s__('DastProfiles|Validation is in progress...'),
},
[PASSED]: {
text: s__(
'DastProfiles|Validation succeeded. Both active and passive scans can be run against the target site.',
),
cssClass: 'gl-text-green-500',
},
[FAILED]: {
text: s__('DastProfiles|Validation failed. Please try again.'),
cssClass: 'gl-text-red-500',
dismissed: this.isSiteValidationTouched,
},
};
const defaultDescription = descriptions[PENDING];
const currentStatusDescription = descriptions[this.validationStatus];
return currentStatusDescription && !currentStatusDescription.dismissed
? currentStatusDescription
: defaultDescription;
},
}, },
async mounted() { async mounted() {
if (this.isEdit) { if (this.isEdit) {
this.form.showValidation = true; this.form.showValidation = true;
if (this.glFeatures.securityOnDemandScansSiteValidation) {
await this.fetchValidationStatus();
this.isSiteValidationActive = this.validationStatusMatches(PASSED);
}
} }
}, },
destroyed() {
clearTimeout(this.fetchValidationTimeout);
this.fetchValidationTimeout = null;
},
methods: { methods: {
async validateSite(validate) {
this.isSiteValidationActive = validate;
this.isSiteValidationTouched = true;
this.tokenId = null;
this.token = null;
if (!validate) {
this.validationStatus = null;
} else {
try {
this.isValidatingSite = true;
await this.fetchValidationStatus();
if (![PASSED, INPROGRESS].some(this.validationStatusMatches)) {
await this.createValidationToken();
}
} catch (exception) {
this.captureException(exception);
this.isSiteValidationActive = false;
} finally {
this.isValidatingSite = false;
}
}
},
validationStatusMatches(status) {
return this.validationStatus === status;
},
async fetchValidationStatus() {
this.isFetchingValidationStatus = true;
try {
const {
data: {
project: { dastSiteValidation },
},
} = await this.$apollo.query({
query: dastSiteValidationQuery,
variables: {
fullPath: this.fullPath,
targetUrl: this.form.fields.targetUrl.value,
},
fetchPolicy: fetchPolicies.NETWORK_ONLY,
});
this.validationStatus = dastSiteValidation?.status || null;
if (this.validationStatusMatches(INPROGRESS)) {
await new Promise(resolve => {
this.fetchValidationTimeout = setTimeout(resolve, DAST_SITE_VALIDATION_POLL_INTERVAL);
});
await this.fetchValidationStatus();
}
} catch (exception) {
this.showErrors({
message: this.i18n.siteValidation.validationStatusFetchError,
});
throw new Error(exception);
} finally {
this.isFetchingValidationStatus = false;
}
},
async createValidationToken() {
const errorMessage = this.i18n.siteValidation.createTokenError;
try {
const {
data: {
dastSiteTokenCreate: { id, token, errors = [] },
},
} = await this.$apollo.mutate({
mutation: dastSiteTokenCreateMutation,
variables: {
fullPath: this.fullPath,
targetUrl: this.form.fields.targetUrl.value,
},
});
if (errors.length) {
this.showErrors({ message: errorMessage, errors });
} else {
this.tokenId = id;
this.token = token;
}
} catch (exception) {
this.showErrors({ message: errorMessage });
throw new Error(exception);
}
},
onSubmit() { onSubmit() {
this.form.showValidation = true; this.form.showValidation = true;
...@@ -317,9 +142,6 @@ export default { ...@@ -317,9 +142,6 @@ export default {
this.$refs[this.$options.modalId].show(); this.$refs[this.$options.modalId].show();
} }
}, },
onValidationSuccess() {
this.validationStatus = PASSED;
},
discard() { discard() {
redirectTo(this.profilesLibraryPath); redirectTo(this.profilesLibraryPath);
}, },
...@@ -381,11 +203,6 @@ export default { ...@@ -381,11 +203,6 @@ export default {
<gl-form-group <gl-form-group
data-testid="target-url-input-group" data-testid="target-url-input-group"
:invalid-feedback="form.fields.targetUrl.feedback" :invalid-feedback="form.fields.targetUrl.feedback"
:description="
isSiteValidationActive && !isValidatingSite
? s__('DastProfiles|Validation must be turned off to change the target URL')
: null
"
:label="s__('DastProfiles|Target URL')" :label="s__('DastProfiles|Target URL')"
> >
<gl-form-input <gl-form-input
...@@ -397,44 +214,9 @@ export default { ...@@ -397,44 +214,9 @@ export default {
required required
type="url" type="url"
:state="form.fields.targetUrl.state" :state="form.fields.targetUrl.state"
:disabled="isSiteValidationActive"
/> />
</gl-form-group> </gl-form-group>
<template v-if="glFeatures.securityOnDemandScansSiteValidation">
<gl-form-group :label="s__('DastProfiles|Validate target site')">
<template #description>
<p
v-if="siteValidationStatusDescription.text"
class="gl-mt-3"
:class="siteValidationStatusDescription.cssClass"
data-testid="siteValidationStatusDescription"
>
{{ siteValidationStatusDescription.text }}
</p>
</template>
<gl-toggle
data-testid="dast-site-validation-toggle"
:value="isSiteValidationActive"
:disabled="isSiteValidationDisabled"
:is-loading="
!isSiteValidationDisabled && (isFetchingValidationStatus || isValidatingSite)
"
@change="validateSite"
/>
</gl-form-group>
<gl-collapse :visible="showValidationSection">
<dast-site-validation
:full-path="fullPath"
:token-id="tokenId"
:token="token"
:target-url="form.fields.targetUrl.value"
@success="onValidationSuccess"
/>
</gl-collapse>
</template>
<hr /> <hr />
<div class="gl-mt-6 gl-pt-6"> <div class="gl-mt-6 gl-pt-6">
...@@ -443,7 +225,6 @@ export default { ...@@ -443,7 +225,6 @@ export default {
variant="success" variant="success"
class="js-no-auto-disable" class="js-no-auto-disable"
data-testid="dast-site-profile-form-submit-button" data-testid="dast-site-profile-form-submit-button"
:disabled="isSubmitDisabled"
:loading="isLoading" :loading="isLoading"
> >
{{ s__('DastProfiles|Save profile') }} {{ s__('DastProfiles|Save profile') }}
......
...@@ -7,14 +7,10 @@ import { GlForm, GlModal } from '@gitlab/ui'; ...@@ -7,14 +7,10 @@ import { GlForm, GlModal } from '@gitlab/ui';
import waitForPromises from 'jest/helpers/wait_for_promises'; import waitForPromises from 'jest/helpers/wait_for_promises';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import DastSiteProfileForm from 'ee/security_configuration/dast_site_profiles_form/components/dast_site_profile_form.vue'; import DastSiteProfileForm from 'ee/security_configuration/dast_site_profiles_form/components/dast_site_profile_form.vue';
import DastSiteValidation from 'ee/security_configuration/dast_site_profiles_form/components/dast_site_validation.vue';
import dastSiteValidationQuery from 'ee/security_configuration/dast_site_profiles_form/graphql/dast_site_validation.query.graphql';
import dastSiteProfileCreateMutation from 'ee/security_configuration/dast_site_profiles_form/graphql/dast_site_profile_create.mutation.graphql'; import dastSiteProfileCreateMutation from 'ee/security_configuration/dast_site_profiles_form/graphql/dast_site_profile_create.mutation.graphql';
import dastSiteProfileUpdateMutation from 'ee/security_configuration/dast_site_profiles_form/graphql/dast_site_profile_update.mutation.graphql'; import dastSiteProfileUpdateMutation from 'ee/security_configuration/dast_site_profiles_form/graphql/dast_site_profile_update.mutation.graphql';
import dastSiteTokenCreateMutation from 'ee/security_configuration/dast_site_profiles_form/graphql/dast_site_token_create.mutation.graphql';
import { siteProfiles } from 'ee_jest/on_demand_scans/mock_data'; import { siteProfiles } from 'ee_jest/on_demand_scans/mock_data';
import * as responses from 'ee_jest/security_configuration/dast_site_profiles_form/mock_data/apollo_mock'; import * as responses from 'ee_jest/security_configuration/dast_site_profiles_form/mock_data/apollo_mock';
import { DAST_SITE_VALIDATION_STATUS } from 'ee/security_configuration/dast_site_profiles_form/constants';
import * as urlUtility from '~/lib/utils/url_utility'; import * as urlUtility from '~/lib/utils/url_utility';
const localVue = createLocalVue(); const localVue = createLocalVue();
...@@ -25,8 +21,6 @@ const fullPath = 'group/project'; ...@@ -25,8 +21,6 @@ const fullPath = 'group/project';
const profilesLibraryPath = `${TEST_HOST}/${fullPath}/-/security/configuration/dast_profiles`; const profilesLibraryPath = `${TEST_HOST}/${fullPath}/-/security/configuration/dast_profiles`;
const profileName = 'My DAST site profile'; const profileName = 'My DAST site profile';
const targetUrl = 'http://example.com'; const targetUrl = 'http://example.com';
const tokenId = '3455';
const token = '33988';
const defaultProps = { const defaultProps = {
profilesLibraryPath, profilesLibraryPath,
...@@ -36,10 +30,6 @@ const defaultProps = { ...@@ -36,10 +30,6 @@ const defaultProps = {
const defaultRequestHandlers = { const defaultRequestHandlers = {
dastSiteProfileCreate: jest.fn().mockResolvedValue(responses.dastSiteProfileCreate()), dastSiteProfileCreate: jest.fn().mockResolvedValue(responses.dastSiteProfileCreate()),
dastSiteProfileUpdate: jest.fn().mockResolvedValue(responses.dastSiteProfileUpdate()), dastSiteProfileUpdate: jest.fn().mockResolvedValue(responses.dastSiteProfileUpdate()),
dastSiteTokenCreate: jest
.fn()
.mockResolvedValue(responses.dastSiteTokenCreate({ id: tokenId, token })),
dastSiteValidation: jest.fn().mockResolvedValue(responses.dastSiteValidation()),
}; };
describe('DastSiteProfileForm', () => { describe('DastSiteProfileForm', () => {
...@@ -52,15 +42,12 @@ describe('DastSiteProfileForm', () => { ...@@ -52,15 +42,12 @@ describe('DastSiteProfileForm', () => {
const findForm = () => wrapper.find(GlForm); const findForm = () => wrapper.find(GlForm);
const findByTestId = testId => wrapper.find(`[data-testid="${testId}"]`); const findByTestId = testId => wrapper.find(`[data-testid="${testId}"]`);
const findProfileNameInput = () => findByTestId('profile-name-input'); const findProfileNameInput = () => findByTestId('profile-name-input');
const findTargetUrlInputGroup = () => findByTestId('target-url-input-group');
const findTargetUrlInput = () => findByTestId('target-url-input'); const findTargetUrlInput = () => findByTestId('target-url-input');
const findSubmitButton = () => findByTestId('dast-site-profile-form-submit-button'); const findSubmitButton = () => findByTestId('dast-site-profile-form-submit-button');
const findCancelButton = () => findByTestId('dast-site-profile-form-cancel-button'); const findCancelButton = () => findByTestId('dast-site-profile-form-cancel-button');
const findCancelModal = () => wrapper.find(GlModal); const findCancelModal = () => wrapper.find(GlModal);
const submitForm = () => findForm().vm.$emit('submit', { preventDefault: () => {} }); const submitForm = () => findForm().vm.$emit('submit', { preventDefault: () => {} });
const findAlert = () => findByTestId('dast-site-profile-form-alert'); const findAlert = () => findByTestId('dast-site-profile-form-alert');
const findSiteValidationToggle = () => findByTestId('dast-site-validation-toggle');
const findDastSiteValidation = () => wrapper.find(DastSiteValidation);
const setFieldValue = async (field, value) => { const setFieldValue = async (field, value) => {
await field.setValue(value); await field.setValue(value);
...@@ -85,10 +72,6 @@ describe('DastSiteProfileForm', () => { ...@@ -85,10 +72,6 @@ describe('DastSiteProfileForm', () => {
requestHandlers.dastSiteProfileUpdate, requestHandlers.dastSiteProfileUpdate,
); );
mockClient.setRequestHandler(dastSiteTokenCreateMutation, requestHandlers.dastSiteTokenCreate);
mockClient.setRequestHandler(dastSiteValidationQuery, requestHandlers.dastSiteValidation);
return mockClient; return mockClient;
}; };
...@@ -149,139 +132,6 @@ describe('DastSiteProfileForm', () => { ...@@ -149,139 +132,6 @@ describe('DastSiteProfileForm', () => {
}); });
}); });
describe('validation', () => {
const enableValidationToggle = async () => {
await setFieldValue(findTargetUrlInput(), targetUrl);
await findSiteValidationToggle().vm.$emit('change', true);
};
describe.each`
title | siteProfile
${'New site profile'} | ${null}
${'Edit site profile'} | ${siteProfileOne}
`('$title with feature flag disabled', ({ siteProfile }) => {
beforeEach(() => {
createFullComponent({
provide: {
glFeatures: { securityOnDemandScansSiteValidation: false },
},
propsData: {
siteProfile,
},
});
});
it('does not render validation components', () => {
expect(findSiteValidationToggle().exists()).toBe(false);
expect(findDastSiteValidation().exists()).toBe(false);
});
it('does not check the target URLs validation status', () => {
expect(requestHandlers.dastSiteValidation).not.toHaveBeenCalled();
});
});
describe('with feature flag enabled', () => {
beforeEach(() => {
createFullComponent({
provide: {
glFeatures: { securityOnDemandScansSiteValidation: true },
},
});
});
it('renders validation components', () => {
expect(findSiteValidationToggle().exists()).toBe(true);
expect(findDastSiteValidation().exists()).toBe(true);
});
it('toggle is disabled until target URL is valid', async () => {
expect(findSiteValidationToggle().props('disabled')).toBe(true);
await setFieldValue(findTargetUrlInput(), targetUrl);
expect(findSiteValidationToggle().props('disabled')).toBe(false);
});
it('disables target URL input when validation is enabled', async () => {
const targetUrlInputGroup = findTargetUrlInputGroup();
const targetUrlInput = findTargetUrlInput();
expect(targetUrlInputGroup.attributes('description')).toBeUndefined();
expect(targetUrlInput.attributes('disabled')).toBeUndefined();
await enableValidationToggle();
await waitForPromises();
expect(targetUrlInputGroup.text()).toContain(
'Validation must be turned off to change the target URL',
);
expect(targetUrlInput.attributes('disabled')).toBe('disabled');
});
it('checks the target URLs validation status when validation is enabled', async () => {
expect(requestHandlers.dastSiteValidation).not.toHaveBeenCalled();
await enableValidationToggle();
expect(requestHandlers.dastSiteValidation).toHaveBeenCalledWith({
fullPath,
targetUrl,
});
});
it('creates a site token if the target URL has not been validated', async () => {
expect(requestHandlers.dastSiteTokenCreate).not.toHaveBeenCalled();
await enableValidationToggle();
await waitForPromises();
expect(requestHandlers.dastSiteTokenCreate).toHaveBeenCalledWith({
fullPath,
targetUrl,
});
expect(findDastSiteValidation().props()).toMatchObject({
tokenId,
token,
});
});
it.each`
description | failingResponse | errorMessageStart
${'target URLs validation status can not be retrieved'} | ${'dastSiteValidation'} | ${'Could not retrieve site validation status'}
${'validation token can not be created'} | ${'dastSiteTokenCreate'} | ${'Could not create site validation token'}
`('shows an error if $description', async ({ failingResponse, errorMessageStart }) => {
respondWith({
[failingResponse]: jest.fn().mockRejectedValue(),
});
expect(findAlert().exists()).toBe(false);
await enableValidationToggle();
await waitForPromises();
expect(findAlert().exists()).toBe(true);
expect(findAlert().text()).toBe(
`${errorMessageStart}. Please refresh the page, or try again later.`,
);
});
it('when validation section is opened and validation succeeds, section is collapsed', async () => {
expect(wrapper.vm.showValidationSection).toBe(false);
await enableValidationToggle();
await waitForPromises();
expect(wrapper.vm.showValidationSection).toBe(true);
await findDastSiteValidation().vm.$emit('success');
expect(wrapper.vm.showValidationSection).toBe(false);
});
});
});
describe.each` describe.each`
title | siteProfile | mutationVars | mutationKind title | siteProfile | mutationVars | mutationKind
${'New site profile'} | ${null} | ${{}} | ${'dastSiteProfileCreate'} ${'New site profile'} | ${null} | ${{}} | ${'dastSiteProfileCreate'}
...@@ -414,84 +264,4 @@ describe('DastSiteProfileForm', () => { ...@@ -414,84 +264,4 @@ describe('DastSiteProfileForm', () => {
}); });
}); });
}); });
describe.each`
givenValidationStatus | expectedDescription | shouldShowDefaultDescriptionAfterToggle | shouldHaveSiteValidationActivated | shouldHaveSiteValidationDisabled | shouldPoll
${DAST_SITE_VALIDATION_STATUS.PENDING} | ${'Site must be validated to run an active scan.'} | ${false} | ${false} | ${false} | ${false}
${DAST_SITE_VALIDATION_STATUS.INPROGRESS} | ${'Validation is in progress...'} | ${false} | ${false} | ${true} | ${true}
${DAST_SITE_VALIDATION_STATUS.PASSED} | ${'Validation succeeded. Both active and passive scans can be run against the target site.'} | ${false} | ${true} | ${false} | ${false}
${DAST_SITE_VALIDATION_STATUS.FAILED} | ${'Validation failed. Please try again.'} | ${true} | ${false} | ${false} | ${false}
`(
'when editing an existing profile and the validation status is "$givenValidationStatus"',
({
givenValidationStatus,
expectedDescription,
shouldHaveSiteValidationActivated,
shouldShowDefaultDescriptionAfterToggle,
shouldHaveSiteValidationDisabled,
shouldPoll,
}) => {
let dastSiteValidationHandler;
beforeEach(() => {
dastSiteValidationHandler = jest
.fn()
.mockResolvedValue(responses.dastSiteValidation(givenValidationStatus));
createFullComponent(
{
provide: {
glFeatures: { securityOnDemandScansSiteValidation: true },
},
propsData: {
siteProfile: siteProfileOne,
},
},
{
dastSiteValidation: dastSiteValidationHandler,
},
);
return wrapper.vm.$nextTick();
});
it('shows the correct status text', () => {
expect(findByTestId('siteValidationStatusDescription').text()).toBe(expectedDescription);
});
it(`shows the correct status text after the validation toggle has been changed`, async () => {
const defaultDescription = 'Site must be validated to run an active scan.';
findSiteValidationToggle().vm.$emit('change', true);
await wrapper.vm.$nextTick();
expect(findByTestId('siteValidationStatusDescription').text()).toBe(
shouldShowDefaultDescriptionAfterToggle ? defaultDescription : expectedDescription,
);
});
it('sets the validation toggle to the correct state', () => {
expect(findSiteValidationToggle().props()).toMatchObject({
value: shouldHaveSiteValidationActivated,
disabled: shouldHaveSiteValidationDisabled,
});
});
it(`should ${shouldPoll ? '' : 'not '}poll the validation status`, async () => {
jest.useFakeTimers();
expect(dastSiteValidationHandler).toHaveBeenCalledTimes(1);
jest.runOnlyPendingTimers();
await waitForPromises();
if (shouldPoll) {
expect(dastSiteValidationHandler).toHaveBeenCalledTimes(2);
} else {
expect(dastSiteValidationHandler).toHaveBeenCalledTimes(1);
}
});
},
);
}); });
...@@ -8413,9 +8413,6 @@ msgstr "" ...@@ -8413,9 +8413,6 @@ msgstr ""
msgid "DastProfiles|Copy HTTP header to clipboard" msgid "DastProfiles|Copy HTTP header to clipboard"
msgstr "" msgstr ""
msgid "DastProfiles|Could not create site validation token. Please refresh the page, or try again later."
msgstr ""
msgid "DastProfiles|Could not create the scanner profile. Please try again." msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr "" msgstr ""
...@@ -8440,9 +8437,6 @@ msgstr "" ...@@ -8440,9 +8437,6 @@ msgstr ""
msgid "DastProfiles|Could not fetch site profiles. Please refresh the page, or try again later." msgid "DastProfiles|Could not fetch site profiles. Please refresh the page, or try again later."
msgstr "" msgstr ""
msgid "DastProfiles|Could not retrieve site validation status. Please refresh the page, or try again later."
msgstr ""
msgid "DastProfiles|Could not update the scanner profile. Please try again." msgid "DastProfiles|Could not update the scanner profile. Please try again."
msgstr "" msgstr ""
...@@ -8557,9 +8551,6 @@ msgstr "" ...@@ -8557,9 +8551,6 @@ msgstr ""
msgid "DastProfiles|Site is not validated yet, please follow the steps." msgid "DastProfiles|Site is not validated yet, please follow the steps."
msgstr "" msgstr ""
msgid "DastProfiles|Site must be validated to run an active scan."
msgstr ""
msgid "DastProfiles|Spider timeout" msgid "DastProfiles|Spider timeout"
msgstr "" msgstr ""
...@@ -8605,27 +8596,12 @@ msgstr "" ...@@ -8605,27 +8596,12 @@ msgstr ""
msgid "DastProfiles|Validate" msgid "DastProfiles|Validate"
msgstr "" msgstr ""
msgid "DastProfiles|Validate target site"
msgstr ""
msgid "DastProfiles|Validating..." msgid "DastProfiles|Validating..."
msgstr "" msgstr ""
msgid "DastProfiles|Validation failed, please make sure that you follow the steps above with the chosen method." msgid "DastProfiles|Validation failed, please make sure that you follow the steps above with the chosen method."
msgstr "" msgstr ""
msgid "DastProfiles|Validation failed. Please try again."
msgstr ""
msgid "DastProfiles|Validation is in progress..."
msgstr ""
msgid "DastProfiles|Validation must be turned off to change the target URL"
msgstr ""
msgid "DastProfiles|Validation succeeded. Both active and passive scans can be run against the target site."
msgstr ""
msgid "Data is still calculating..." msgid "Data is still calculating..."
msgstr "" msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment