diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-17 06:13:50 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-17 06:13:50 +0300 |
commit | eac5de031737387f9e00be37ae429a426fe7d19d (patch) | |
tree | dee06fb1b4d18c362de32b41f30e77fd577154f7 /app | |
parent | e7ddd83a4484ff9fdf355d8eb726db9bfd3dd521 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
3 files changed, 88 insertions, 10 deletions
diff --git a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue index ccfe773b01f..33ae747df22 100644 --- a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue +++ b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue @@ -29,8 +29,10 @@ import { EVENT_ACTION, EXPANDED_VARIABLES_NOTE, FLAG_LINK_TITLE, + MASKED_VALUE_MIN_LENGTH, VARIABLE_ACTIONS, variableOptions, + WHITESPACE_REG_EX, } from '../constants'; import CiEnvironmentsDropdown from './ci_environments_dropdown.vue'; import { awsTokenList } from './ci_variable_autocomplete_tokens'; @@ -54,21 +56,30 @@ export const i18n = { maskedDescription: s__( 'CiVariables|Variable will be masked in job logs. Requires values to meet regular expression requirements.', ), + maskedValueMinLengthValidationText: s__( + 'CiVariables|The value must have at least %{charsAmount} characters.', + ), modalDeleteMessage: s__('CiVariables|Do you want to delete the variable %{key}?'), protectedField: s__('CiVariables|Protect variable'), protectedDescription: s__( 'CiVariables|Export variable to pipelines running on protected branches and tags only.', ), + unsupportedCharsValidationText: s__( + 'CiVariables|This value cannot be masked because it contains the following characters: %{unsupportedChars}.', + ), + unsupportedAndWhitespaceCharsValidationText: s__( + 'CiVariables|This value cannot be masked because it contains the following characters: %{unsupportedChars} and whitespace characters.', + ), valueFeedback: { rawHelpText: s__('CiVariables|Variable value will be evaluated as raw string.'), - maskedReqsNotMet: s__( - 'CiVariables|This variable value does not meet the masking requirements.', - ), }, variableReferenceTitle: s__('CiVariables|Value might contain a variable reference'), variableReferenceDescription: s__( 'CiVariables|Unselect "Expand variable reference" if you want to use the variable value as a raw string.', ), + whitespaceCharsValidationText: s__( + 'CiVariables|This value cannot be masked because it contains the following characters: whitespace characters.', + ), type: __('Type'), value: __('Value'), }; @@ -169,11 +180,76 @@ export default { isEditing() { return this.mode === EDIT_VARIABLE_ACTION; }, + isMaskedValueContainsWhitespaceChars() { + return this.isValueMaskable && WHITESPACE_REG_EX.test(this.variable.value); + }, maskedRegexToUse() { return this.variable.raw ? this.maskableRawRegex : this.maskableRegex; }, - maskedReqsNotMetText() { - return !this.isMaskedReqsMet ? this.$options.i18n.valueFeedback.maskedReqsNotMet : ''; + maskedSupportedCharsRegEx() { + const supportedChars = this.maskedRegexToUse.replace('^', '').replace(/{(\d,)}\$/, ''); + return new RegExp(supportedChars, 'g'); + }, + maskedValueMinLengthValidationText() { + return sprintf(this.$options.i18n.maskedValueMinLengthValidationText, { + charsAmount: MASKED_VALUE_MIN_LENGTH, + }); + }, + unsupportedCharsList() { + if (this.isMaskedReqsMet) { + return []; + } + + return [ + ...new Set( + this.variable.value + .replace(WHITESPACE_REG_EX, '') + .replace(this.maskedSupportedCharsRegEx, '') + .split(''), + ), + ]; + }, + unsupportedChars() { + return this.unsupportedCharsList.join(', '); + }, + unsupportedCharsValidationText() { + return sprintf( + this.$options.i18n.unsupportedCharsValidationText, + { + unsupportedChars: this.unsupportedChars, + }, + false, + ); + }, + unsupportedAndWhitespaceCharsValidationText() { + return sprintf( + this.$options.i18n.unsupportedAndWhitespaceCharsValidationText, + { + unsupportedChars: this.unsupportedChars, + }, + false, + ); + }, + maskedValidationIssuesText() { + if (this.isMaskedReqsMet) { + return ''; + } + + let validationIssuesText = ''; + + if (this.unsupportedCharsList.length && !this.isMaskedValueContainsWhitespaceChars) { + validationIssuesText = this.unsupportedCharsValidationText; + } else if (this.unsupportedCharsList.length && this.isMaskedValueContainsWhitespaceChars) { + validationIssuesText = this.unsupportedAndWhitespaceCharsValidationText; + } else if (!this.unsupportedCharsList.length && this.isMaskedValueContainsWhitespaceChars) { + validationIssuesText = this.$options.i18n.whitespaceCharsValidationText; + } + + if (this.variable.value.length < MASKED_VALUE_MIN_LENGTH) { + validationIssuesText += ` ${this.maskedValueMinLengthValidationText}`; + } + + return validationIssuesText.trim(); }, modalActionText() { return this.isEditing ? this.$options.i18n.editVariable : this.$options.i18n.addVariable; @@ -218,9 +294,7 @@ export default { let property; if (this.isValueMaskable) { - const supportedChars = this.maskedRegexToUse.replace('^', '').replace(/{(\d,)}\$/, ''); - const regex = new RegExp(supportedChars, 'g'); - property = this.variable.value.replace(regex, ''); + property = this.variable.value.replace(this.maskedSupportedCharsRegEx, ''); } else if (this.hasVariableReference) { property = '$'; } @@ -382,7 +456,7 @@ export default { label-for="ci-variable-value" class="gl-border-none gl-mb-n2" data-testid="ci-variable-value-label" - :invalid-feedback="maskedReqsNotMetText" + :invalid-feedback="maskedValidationIssuesText" :state="isValueValid" > <gl-form-textarea diff --git a/app/assets/javascripts/ci/ci_variable_list/constants.js b/app/assets/javascripts/ci/ci_variable_list/constants.js index d85827b8220..4ec7333f465 100644 --- a/app/assets/javascripts/ci/ci_variable_list/constants.js +++ b/app/assets/javascripts/ci/ci_variable_list/constants.js @@ -2,6 +2,10 @@ import { __, s__, sprintf } from '~/locale'; export const ENVIRONMENT_QUERY_LIMIT = 30; +export const MASKED_VALUE_MIN_LENGTH = 8; + +export const WHITESPACE_REG_EX = /\s/; + export const SORT_DIRECTIONS = { ASC: 'KEY_ASC', DESC: 'KEY_DESC', diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml index ca1fef6eb32..ee1516facbc 100644 --- a/app/views/projects/_new_project_fields.html.haml +++ b/app/views/projects/_new_project_fields.html.haml @@ -25,7 +25,7 @@ input_name: 'project[namespace_id]', root_url: root_url, track_label: track_label, - user_namespace_id: current_user.namespace.id } } + user_namespace_id: current_user.namespace_id } } - else .input-group-prepend.static-namespace.flex-shrink-0.has-tooltip{ title: user_url(current_user.username) + '/' } .input-group-text.border-0 |