Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-05-06 00:07:56 +00:00
parent a297076878
commit f38bcf2e44
81 changed files with 396 additions and 172 deletions

View File

@ -60,7 +60,7 @@ export default {
async endEditingLink() {
this.isEditing = false;
this.linkHref = await this.contentEditor.resolveLink(this.linkCanonicalSrc);
this.linkHref = await this.contentEditor.resolveUrl(this.linkCanonicalSrc);
if (!this.linkCanonicalSrc && !this.linkHref) {
this.removeLink();

View File

@ -114,7 +114,7 @@ export default {
async saveEditedMedia() {
this.isUpdating = true;
this.mediaSrc = await this.contentEditor.resolveLink(this.mediaCanonicalSrc);
this.mediaSrc = await this.contentEditor.resolveUrl(this.mediaCanonicalSrc);
const position = this.tiptapEditor.state.selection.from;
@ -151,7 +151,7 @@ export default {
this.mediaAlt = alt;
this.mediaCanonicalSrc = canonicalSrc || src;
this.isUploading = uploading;
this.mediaSrc = await this.contentEditor.resolveLink(this.mediaCanonicalSrc);
this.mediaSrc = await this.contentEditor.resolveUrl(this.mediaCanonicalSrc);
this.isUpdating = false;
},

View File

@ -43,7 +43,7 @@ export class ContentEditor {
});
}
resolveAssetUrl(canonicalSrc) {
resolveUrl(canonicalSrc) {
return this._assetResolver.resolveUrl(canonicalSrc);
}

View File

@ -1,9 +1,9 @@
= render Pajamas::AlertComponent.new(title: _('Too many changes to show.'),
variant: :warning,
alert_class: 'gl-mb-5') do
.gl-alert-body
alert_class: 'gl-mb-5') do |c|
= c.body do
= message
.gl-alert-actions
= c.actions do
= diff_link
= patch_link

View File

@ -11,4 +11,9 @@
- if @title
%h4.gl-alert-title
= @title
= content
- if body?
.gl-alert-body
= body
- if actions?
.gl-alert-actions
= actions

View File

@ -36,6 +36,9 @@ module Pajamas
delegate :sprite_icon, to: :helpers
renders_one :body
renders_one :actions
ICONS = {
info: 'information-o',
warning: 'warning',

View File

@ -18,9 +18,9 @@
- else
= render Pajamas::AlertComponent.new(variant: :warning,
dismissible: false,
title: _('Service Ping payload not found in the application cache')) do
title: _('Service Ping payload not found in the application cache')) do |c|
.gl-alert-body
= c.body do
- enable_service_ping_link_url = help_page_path('user/admin_area/settings/usage_statistics', anchor: 'enable-or-disable-usage-statistics')
- enable_service_ping_link = '<a href="%{url}">'.html_safe % { url: enable_service_ping_link_url }
- generate_manually_link_url = help_page_path('administration/troubleshooting/gitlab_rails_cheat_sheet', anchor: 'generate-service-ping')

View File

@ -6,9 +6,9 @@
alert_data: { feature_id: Users::CalloutsHelper::SECURITY_NEWSLETTER_CALLOUT,
dismiss_endpoint: callouts_path,
defer_links: 'true' },
close_button_data: { testid: 'close-security-newsletter-callout' }) do
.gl-alert-body
close_button_data: { testid: 'close-security-newsletter-callout' }) do |c|
= c.body do
= s_('AdminArea|Sign up for the GitLab Security Newsletter to get notified for security updates.')
.gl-alert-actions
= c.actions do
= link_to 'https://about.gitlab.com/company/preference-center/', target: '_blank', rel: 'noreferrer noopener', class: 'deferred-link gl-alert-action btn-confirm btn-md gl-button' do
= s_('AdminArea|Sign up for the GitLab newsletter')

View File

@ -27,8 +27,8 @@
- if @group.new_record?
.form-group.row
.offset-sm-2.col-sm-10
= render Pajamas::AlertComponent.new(dismissible: false) do
.gl-alert-body
= render Pajamas::AlertComponent.new(dismissible: false) do |c|
= c.body do
= render 'shared/group_tips'
.form-actions
= f.submit _('Create group'), class: "gl-button btn btn-confirm"

View File

@ -16,8 +16,8 @@
.col-md-12
= render Pajamas::AlertComponent.new(variant: :danger,
alert_class: 'gl-mb-5',
alert_data: { testid: 'last-repository-check-failed-alert' }) do
.gl-alert-body
alert_data: { testid: 'last-repository-check-failed-alert' }) do |c|
= c.body do
- last_check_message = _("Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages.")
- last_check_message = last_check_message % { last_check_timestamp: time_ago_with_tooltip(@project.last_repository_check_at) }
= last_check_message.html_safe

View File

@ -26,8 +26,8 @@
%td
= render Pajamas::AlertComponent.new(variant: :danger,
dismissible: false,
title: project.full_name) do
.gl-alert-actions
title: project.full_name) do |c|
= c.actions do
= link_to _('Disable'), admin_namespace_project_runner_project_path(project.namespace, project, runner_project), method: :delete, class: 'btn gl-alert-action btn-confirm btn-md gl-button'
%table.table{ data: { testid: 'unassigned-projects' } }

View File

@ -1,8 +1,8 @@
- if registration_features_can_be_prompted?
= render Pajamas::AlertComponent.new(variant: :tip,
alert_class: 'gl-my-5',
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
= render 'shared/registration_features_discovery_message', feature_title: s_('RegistrationFeatures|send emails to users')
.top-area

View File

@ -7,13 +7,13 @@
%span.gl-ml-2= s_('ClusterIntegration|Kubernetes cluster is being created...')
= render Pajamas::AlertComponent.new(variant: :warning,
alert_class: 'hidden js-cluster-api-unreachable') do
.gl-alert-body
alert_class: 'hidden js-cluster-api-unreachable') do |c|
= c.body do
= s_('ClusterIntegration|Your cluster API is unreachable. Please ensure your API URL is correct.')
= render Pajamas::AlertComponent.new(variant: :warning,
alert_class: 'hidden js-cluster-authentication-failure js-cluster-api-unreachable') do
.gl-alert-body
alert_class: 'hidden js-cluster-authentication-failure js-cluster-api-unreachable') do |c|
= c.body do
= s_('ClusterIntegration|There was a problem authenticating with your cluster. Please ensure your CA Certificate and Token are valid.')
.hidden.js-cluster-success.bs-callout.bs-callout-success{ role: 'alert' }

View File

@ -1,5 +1,5 @@
= render Pajamas::AlertComponent.new(variant: :warning, dismissible: false, alert_class: 'gl-mt-6 gl-mb-3') do
.gl-alert-body
= render Pajamas::AlertComponent.new(variant: :warning, dismissible: false, alert_class: 'gl-mt-6 gl-mb-3') do |c|
= c.body do
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe
- issue_link_start = link_start % { url: 'https://gitlab.com/gitlab-org/configure/general/-/issues/199' }
- docs_link_start = link_start % { url: help_page_path('user/clusters/agent/index.md') }

View File

@ -2,9 +2,9 @@
= render Pajamas::AlertComponent.new(title: s_('ClusterIntegration|Did you know?'),
alert_class: 'gcp-signup-offer',
alert_data: { feature_id: Users::CalloutsHelper::GCP_SIGNUP_OFFER, dismiss_endpoint: callouts_path }) do
.gl-alert-body
alert_data: { feature_id: Users::CalloutsHelper::GCP_SIGNUP_OFFER, dismiss_endpoint: callouts_path }) do |c|
= c.body do
= s_('ClusterIntegration|Every new Google Cloud Platform (GCP) account receives $300 in credit upon %{sign_up_link}. In partnership with Google, GitLab is able to offer an additional $200 for both new and existing GCP accounts to get started with GitLab\'s Google Kubernetes Engine Integration.').html_safe % { sign_up_link: link }
.gl-alert-actions
= c.actions do
%a.gl-button.btn-confirm.text-decoration-none{ href: 'https://cloud.google.com/partners/partnercredit/?pcn_code=0014M00001h35gDQAQ#contact-form', target: '_blank', rel: 'noopener noreferrer' }
= s_("ClusterIntegration|Apply for credit")

View File

@ -5,8 +5,8 @@
= s_('GroupsNew|Import groups from another instance of GitLab')
= link_to _('History'), history_import_bulk_imports_path, class: 'gl-link gl-ml-auto'
= render Pajamas::AlertComponent.new(dismissible: false,
variant: :warning) do
.gl-alert-body
variant: :warning) do |c|
= c.body do
- docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index.md') }
- docs_link_end = '</a>'.html_safe
= s_('GroupsNew|Not all related objects are migrated. %{docs_link_start}More info%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: docs_link_end }

View File

@ -7,8 +7,8 @@
%h4
= _('Import group from file')
= render Pajamas::AlertComponent.new(variant: :warning,
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
- docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index.md') }
- link_end = '</a>'.html_safe
= s_('GroupsNew|This feature is deprecated and replaced by %{docs_link_start}group migration%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: link_end }

View File

@ -3,8 +3,8 @@
.sub-section
%h4= s_('GroupSettings|Export group')
%p= _('Export this group with all related data.')
= render Pajamas::AlertComponent.new(variant: :warning, dismissible: false, alert_class: 'gl-mb-4') do
.gl-alert-body
= render Pajamas::AlertComponent.new(variant: :warning, dismissible: false, alert_class: 'gl-mb-4') do |c|
= c.body do
- docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index.md') }
- docs_link_end = '</a>'.html_safe
= s_('GroupsNew|This feature is deprecated and replaced by %{docs_link_start}group migration%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: docs_link_end }
@ -12,8 +12,8 @@
- export_information = _('After the export is complete, download the data file from a notification email or from this page. You can then import the data file from the %{strong_text_start}Create new group%{strong_text_end} page of another GitLab instance.') % { strong_text_start: '<strong>'.html_safe, strong_text_end: '</strong>'.html_safe}
= export_information.html_safe
= link_to _('Learn more.'), help_page_path('user/group/settings/import_export.md'), target: '_blank', rel: 'noopener noreferrer'
= render Pajamas::AlertComponent.new(dismissible: false, alert_class: 'gl-mb-5') do
.gl-alert-body
= render Pajamas::AlertComponent.new(dismissible: false, alert_class: 'gl-mb-5') do |c|
= c.body do
%p.gl-mb-0
%p= _('The following items will be exported:')
%ul

View File

@ -1,8 +1,8 @@
- remove_form_id = local_assigns.fetch(:remove_form_id, nil)
- if group.paid?
= render Pajamas::AlertComponent.new(dismissible: false, alert_class: 'gl-mb-5', alert_data: { testid: 'group-has-linked-subscription-alert' }) do
.gl-alert-body
= render Pajamas::AlertComponent.new(dismissible: false, alert_class: 'gl-mb-5', alert_data: { testid: 'group-has-linked-subscription-alert' }) do |c|
= c.body do
= html_escape(_("This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group.")) % { linkStart: "<a href=\"#{help_page_path('subscriptions/index', anchor: 'change-the-linked-namespace')}\">".html_safe, linkEnd: '</a>'.html_safe }
.js-confirm-danger{ data: group_settings_confirm_modal_data(group, remove_form_id) }

View File

@ -13,7 +13,7 @@
%li= s_('GroupSettings|You will need to update your local repositories to point to the new location.')
%li= s_("GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.")
- if group.paid?
= render Pajamas::AlertComponent.new(dismissible: false, alert_class: 'gl-mb-5') do
.gl-alert-body
= render Pajamas::AlertComponent.new(dismissible: false, alert_class: 'gl-mb-5') do |c|
= c.body do
= html_escape(_("This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group.")) % { linkStart: "<a href=\"#{help_page_path('subscriptions/index', anchor: 'change-the-linked-namespace')}\">".html_safe, linkEnd: '</a>'.html_safe }
.js-transfer-group-form{ data: initial_data }

View File

@ -1,7 +1,7 @@
- if @errors.present?
= render Pajamas::AlertComponent.new(variant: :danger,
dismissible: false,
alert_class: 'gl-mb-5') do
.gl-alert-body
alert_class: 'gl-mb-5') do |c|
= c.body do
- @errors.each do |error|
= error

View File

@ -5,10 +5,10 @@
alert_class: 'js-registration-enabled-callout',
alert_data: { feature_id: Users::CalloutsHelper::REGISTRATION_ENABLED_CALLOUT,
dismiss_endpoint: callouts_path },
close_button_data: { testid: 'close-registration-enabled-callout' }) do
.gl-alert-body
close_button_data: { testid: 'close-registration-enabled-callout' }) do |c|
= c.body do
= _('Only allow anyone to register for accounts on GitLab instances that you intend to be used by anyone. Allowing anyone to register makes GitLab instances more vulnerable.')
.gl-alert-actions
= c.actions do
= link_to general_admin_application_settings_path(anchor: 'js-signup-settings'), class: 'btn gl-alert-action btn-confirm btn-md gl-button' do
%span.gl-button-text
= _('Turn off')

View File

@ -8,7 +8,7 @@
alert_data: { feature_id: banner_info[:callouts_feature_name],
dismiss_endpoint: banner_info[:callouts_path],
group_id: namespace.id,
defer_links: "true" }) do
.gl-alert-body
defer_links: "true" }) do |c|
= c.body do
= banner_info[:text]
= banner_info[:learn_more_link]

View File

@ -3,15 +3,15 @@
- if current_user.ldap_user?
= render Pajamas::AlertComponent.new(alert_class: 'gl-my-5',
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
= s_('Profiles|Some options are unavailable for LDAP accounts')
- if params[:two_factor_auth_enabled_successfully]
= render Pajamas::AlertComponent.new(variant: :success,
alert_class: 'gl-my-5',
close_button_class: 'js-close-2fa-enabled-success-alert') do
.gl-alert-body
close_button_class: 'js-close-2fa-enabled-success-alert') do |c|
= c.body do
= html_escape(_('You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}.')) % { anchorOpen: '<a href="%{href}">'.html_safe % { href: help_page_path('user/profile/account/two_factor_authentication', anchor: 'generate-new-recovery-codes-using-ssh') }, anchorClose: '</a>'.html_safe }
.row.gl-mt-3.js-search-settings-section

View File

@ -3,8 +3,8 @@
%div
- if @user.errors.any?
= render Pajamas::AlertComponent.new(variant: :danger) do
.gl-alert-body
= render Pajamas::AlertComponent.new(variant: :danger) do |c|
= c.body do
%ul
- @user.errors.full_messages.each do |msg|
%li= msg

View File

@ -42,8 +42,8 @@
- if @error
= render Pajamas::AlertComponent.new(title: @error[:message],
variant: :danger,
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
= link_to _('Try the troubleshooting steps here.'), help_page_path('user/profile/account/two_factor_authentication.md', anchor: 'troubleshooting'), target: '_blank', rel: 'noopener noreferrer'
.form-group

View File

@ -3,7 +3,7 @@
= render Pajamas::AlertComponent.new(variant: :warning,
dismissible: false,
alert_class: 'project-deletion-failed-message') do
.gl-alert-body
alert_class: 'project-deletion-failed-message') do |c|
= c.body do
This project was scheduled for deletion, but failed with the following message:
= project.delete_error

View File

@ -2,8 +2,8 @@
- if event && show_last_push_widget?(event)
= render Pajamas::AlertComponent.new(variant: :success,
alert_class: 'gl-mt-3',
close_button_class: 'js-close-banner') do
.gl-alert-body
close_button_class: 'js-close-banner') do |c|
= c.body do
%span= s_("LastPushEvent|You pushed to")
%strong.gl-display-inline-flex.gl-max-w-50p{ data: { toggle: 'tooltip' }, title: event.ref_name }
= link_to event.ref_name, project_commits_path(event.project, event.ref_name), class: 'ref-name gl-text-truncate'
@ -15,6 +15,6 @@
#{time_ago_with_tooltip(event.created_at)}
- if can?(current_user, :create_merge_request_in, event.project.default_merge_request_target)
.gl-alert-actions
= c.actions do
= link_to new_mr_path_from_push_event(event), title: _("New merge request"), class: "btn gl-button btn-confirm qa-create-merge-request" do
#{ _('Create merge request') }

View File

@ -39,8 +39,8 @@
= project_tip.html_safe
= render Pajamas::AlertComponent.new(alert_class: "gl-mb-4 gl-display-none js-user-readme-repo",
dismissible: false,
variant: :success) do
.gl-alert-body
variant: :success) do |c|
= c.body do
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/profile/index', anchor: 'add-details-to-your-profile-with-a-readme') }
= html_escape(_('%{project_path} is a project that you can use to add a README to your GitLab profile. Create a public project and initialize the repository with a README to get started. %{help_link_start}Learn more.%{help_link_end}')) % { project_path: "<strong>#{current_user.username} / #{current_user.username}</strong>".html_safe, help_link_start: help_link_start, help_link_end: '</a>'.html_safe }

View File

@ -6,12 +6,13 @@
- if @conflict
= render Pajamas::AlertComponent.new(alert_class: 'gl-mb-5 gl-mt-5',
variant: :danger,
dismissible: false) do
dismissible: false) do |c|
- blob_url = project_blob_path(@project, @id)
- external_link_icon = content_tag 'span', { aria: { label: _('Opens new window') }} do
- sprite_icon('external-link', css_class: 'gl-icon').html_safe
- blob_link_start = '<a href="%{url}" class="gl-link" target="_blank" rel="noopener noreferrer">'.html_safe % { url: blob_url }
= _('Someone edited the file the same time you did. Please check out %{link_start}the file %{icon}%{link_end} and make sure your changes will not unintentionally remove theirs.').html_safe % { link_start: blob_link_start, link_end: '</a>'.html_safe , icon: external_link_icon }
= c.body do
= _('Someone edited the file the same time you did. Please check out %{link_start}the file %{icon}%{link_end} and make sure your changes will not unintentionally remove theirs.').html_safe % { link_start: blob_link_start, link_end: '</a>'.html_safe , icon: external_link_icon }
%h3.page-title.blob-edit-page-title

View File

@ -2,8 +2,8 @@
- default_ref = params[:ref] || @project.default_branch
- if @error
= render Pajamas::AlertComponent.new(variant: :danger) do
.gl-alert-body
= render Pajamas::AlertComponent.new(variant: :danger) do |c|
= c.body do
= @error
%h3.page-title
= _('New Branch')

View File

@ -36,8 +36,8 @@
- if hidden > 0
%li
= render Pajamas::AlertComponent.new(variant: :warning,
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
= n_('%s additional commit has been omitted to prevent performance issues.', '%s additional commits have been omitted to prevent performance issues.', hidden) % number_with_delimiter(hidden)
- if can_update_merge_request && context_commits&.empty?

View File

@ -3,8 +3,8 @@
= render Pajamas::AlertComponent.new(title: _('Fork Error!'),
variant: :danger,
alert_class: 'gl-mt-5',
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
%p
= _("You tried to fork %{link_to_the_project} but it failed for the following reason:").html_safe % { link_to_the_project: link_to_project(@project) }
@ -17,5 +17,5 @@
- else
= error
.gl-alert-actions
= link_to _('Try to fork again'), new_project_fork_path(@project), title: _("Fork"), class: "btn gl-alert-action btn-info btn-md gl-button"
= c.actions do
= link_to _('Try to fork again'), new_project_fork_path(@project), title: _("Fork"), class: "btn gl-alert-action btn-info btn-md gl-button"

View File

@ -3,6 +3,6 @@
- service_desk_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: service_desk_link_url }
= render Pajamas::AlertComponent.new(variant: :warning,
alert_class: 'hide js-alert-moved-from-service-desk-warning gl-mt-5') do
.gl-alert-body.gl-mr-3
alert_class: 'hide js-alert-moved-from-service-desk-warning gl-mt-5') do |c|
= c.body do
= s_('This project does not have %{service_desk_link_start}Service Desk%{service_desk_link_end} enabled, so the user who created the issue will no longer receive email notifications about new activity.').html_safe % { service_desk_link_start: service_desk_link_start, service_desk_link_end: '</a>'.html_safe }

View File

@ -5,8 +5,8 @@
- @content_class = 'limit-container-width' unless fluid_layout
- if @teams_error_message
= render Pajamas::AlertComponent.new(variant: :danger) do
.gl-alert-body
= render Pajamas::AlertComponent.new(variant: :danger) do |c|
= c.body do
= @teams_error_message
%h3

View File

@ -8,8 +8,8 @@
- if @merge_request.closed_or_merged_without_fork?
= render Pajamas::AlertComponent.new(alert_class: 'gl-mb-5',
variant: :danger,
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
= _('The source project of this merge request has been removed.')
.detail-page-header.border-bottom-0.pt-0.pb-0

View File

@ -10,8 +10,8 @@
= render "projects/merge_requests/mr_box"
= render Pajamas::AlertComponent.new(variant: :danger,
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
- if @merge_request.for_fork? && !@merge_request.source_project
= err_fork_project_removed
- elsif !@merge_request.source_branch_exists?

View File

@ -14,8 +14,8 @@
- if can?(current_user, :read_issue, @project) && @milestone.total_issues_count == 0
= render Pajamas::AlertComponent.new(dismissible: false,
alert_data: { testid: 'no-issues-alert' },
alert_class: 'gl-mt-3 gl-mb-5') do
.gl-alert-body
alert_class: 'gl-mt-3 gl-mb-5') do |c|
= c.body do
= _('Assign some issues to this milestone.')
- else
= render 'shared/milestones/milestone_complete_alert', milestone: @milestone do

View File

@ -37,8 +37,8 @@
.panel-footer
= f.submit _('Mirror repository'), class: 'gl-button btn btn-confirm js-mirror-submit qa-mirror-repository-button', name: :update_remote_mirror
- else
= render Pajamas::AlertComponent.new(dismissible: false) do
.gl-alert-body
= render Pajamas::AlertComponent.new(dismissible: false) do |c|
= c.body do
= _('Mirror settings are only available to GitLab administrators.')
.panel.panel-default

View File

@ -1,7 +1,8 @@
- if domain_presenter.errors.any?
= render Pajamas::AlertComponent.new(variant: :danger, dismissible: false) do
- domain_presenter.errors.full_messages.each do |msg|
= msg
= render Pajamas::AlertComponent.new(variant: :danger, dismissible: false) do |c|
= c.body do
- domain_presenter.errors.full_messages.each do |msg|
= msg
.form-group.border-section
.row

View File

@ -7,8 +7,8 @@
-# For example, we can get the link to each tracker with scoped_edit_integration_path(tracker, tracker.project)
= render Pajamas::AlertComponent.new(title: s_('ExternalIssueIntegration|Another issue tracker is already in use'),
variant: :warning,
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
= s_('ExternalIssueIntegration|Only one issue tracker integration can be active at a time. Please disable the active tracker first and try again.')
%h2.gl-mb-4

View File

@ -1,12 +1,12 @@
- if show_auto_devops_implicitly_enabled_banner?(project, current_user)
= render Pajamas::AlertComponent.new(alert_class: 'qa-auto-devops-banner auto-devops-implicitly-enabled-banner',
close_button_class: 'hide-auto-devops-implicitly-enabled-banner',
close_button_data: { project_id: project.id }) do
.gl-alert-body
close_button_data: { project_id: project.id }) do |c|
= c.body do
= s_("AutoDevOps|The Auto DevOps pipeline has been enabled and will be used if no alternative CI configuration file is found.")
- unless Gitlab.config.registry.enabled
%div
= _('Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for Auto DevOps to work.')
.gl-alert-actions
= c.actions do
= link_to _('Settings'), project_settings_ci_cd_path(project), class: 'alert-link btn gl-button btn-confirm'
= link_to _('More information'), help_page_path('topics/autodevops/index.md'), target: '_blank', class: 'alert-link btn gl-button btn-default gl-ml-3'

View File

@ -24,8 +24,8 @@
= render Pajamas::AlertComponent.new(variant: :danger,
alert_class: 'gl-mt-3 js-import-url-error hide',
dismissible: false,
close_button_class: 'js-close-2fa-enabled-success-alert') do
.gl-alert-body
close_button_class: 'js-close-2fa-enabled-success-alert') do |c|
= c.body do
= s_('Import|There is not a valid Git repository at this URL. If your HTTP repository is not publicly accessible, verify your credentials.')
= render_if_exists 'shared/ee/import_form', f: f, ci_cd_only: ci_cd_only
.row

View File

@ -1,9 +1,9 @@
- if show_no_password_message?
= render Pajamas::AlertComponent.new(variant: :warning,
alert_class: 'js-no-password-message',
close_button_class: 'js-hide-no-password-message') do
.gl-alert-body
close_button_class: 'js-hide-no-password-message') do |c|
= c.body do
= no_password_message
.gl-alert-actions
= c.actions do
= link_to _('Remind later'), '#', class: 'js-hide-no-password-message gl-alert-action btn btn-confirm btn-md gl-button'
= link_to _("Don't show again"), profile_path(user: { hide_no_password: true }), method: :put, role: 'button', class: 'gl-alert-action btn btn-default btn-md gl-button'

View File

@ -1,9 +1,9 @@
- if show_no_ssh_key_message?
= render Pajamas::AlertComponent.new(variant: :warning,
alert_class: 'js-no-ssh-message',
close_button_class: 'js-hide-no-ssh-message') do
.gl-alert-body
close_button_class: 'js-hide-no-ssh-message') do |c|
= c.body do
= s_("MissingSSHKeyWarningLink|You can't push or pull repositories using SSH until you add an SSH key to your profile.")
.gl-alert-actions
= c.actions do
= link_to s_('MissingSSHKeyWarningLink|Add SSH key'), profile_keys_path, class: "gl-alert-action btn btn-confirm btn-md gl-button"
= link_to s_("MissingSSHKeyWarningLink|Don't show again"), profile_path(user: { hide_no_ssh_key: true }), method: :put, role: 'button', class: 'gl-alert-action btn btn-default btn-md gl-button'

View File

@ -1,6 +1,6 @@
- if outdated_browser?
= render Pajamas::AlertComponent.new(variant: :danger, dismissible: false) do
.gl-alert-body
= render Pajamas::AlertComponent.new(variant: :danger, dismissible: false) do |c|
= c.body do
= s_('OutdatedBrowser|GitLab may not work properly, because you are using an outdated web browser.')
%br
- browser_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('install/requirements', anchor: 'supported-web-browsers') }

View File

@ -1,9 +1,9 @@
- if cookies[:hide_project_limit_message].blank? && !current_user.hide_project_limit && !current_user.can_create_project? && current_user.projects_limit > 0
= render Pajamas::AlertComponent.new(variant: :warning,
dismissible: false,
alert_class: 'project-limit-message') do
.gl-alert-body
alert_class: 'project-limit-message') do |c|
= c.body do
= _("You won't be able to create new projects because you have reached your project limit.")
.gl-alert-actions
= c.actions do
= link_to _('Remind later'), '#', class: 'alert-link hide-project-limit-message btn gl-button btn-confirm'
= link_to _("Don't show again"), profile_path(user: {hide_project_limit: true}), method: :put, class: 'alert-link btn gl-button btn-default gl-ml-3'

View File

@ -1,10 +1,10 @@
- if session[:ask_for_usage_stats_consent]
= render Pajamas::AlertComponent.new(alert_class: 'service-ping-consent-message') do
.gl-alert-body
= render Pajamas::AlertComponent.new(alert_class: 'service-ping-consent-message') do |c|
= c.body do
- docs_link = link_to _('collect usage information'), help_page_path('user/admin_area/settings/usage_statistics.md'), class: 'gl-link'
- settings_link = link_to _('your settings'), metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), class: 'gl-link'
= s_('To help improve GitLab, we would like to periodically %{docs_link}. This can be changed at any time in %{settings_link}.').html_safe % { docs_link: docs_link, settings_link: settings_link }
.gl-alert-actions.gl-mt-3
= c.actions do
- send_service_data_path = admin_application_settings_path(application_setting: { version_check_enabled: 1, usage_ping_enabled: 1 })
- not_now_path = admin_application_settings_path(application_setting: { version_check_enabled: 0, usage_ping_enabled: 0 })
= link_to _("Send service data"), send_service_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-service-ping-enabled': true, class: 'js-service-ping-consent-action alert-link btn gl-button btn-info'

View File

@ -3,10 +3,10 @@
alert_data: { feature_id: Users::CalloutsHelper::TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK,
dismiss_endpoint: callouts_path,
defer_links: 'true' },
close_button_data: { testid: 'close-account-recovery-regular-check-callout' }) do
.gl-alert-body
close_button_data: { testid: 'close-account-recovery-regular-check-callout' }) do |c|
= c.body do
= s_('Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place.')
= link_to _('Learn more.'), help_page_path('user/profile/account/two_factor_authentication', anchor: 'recovery-codes'), target: '_blank', rel: 'noopener noreferrer'
.gl-alert-actions
= c.actions do
= link_to profile_two_factor_auth_path, class: 'deferred-link btn gl-alert-action btn-confirm btn-md gl-button' do
= s_('Profiles|Manage two-factor authentication')

View File

@ -1,6 +1,6 @@
= render Pajamas::AlertComponent.new(alert_class: 'gl-my-5',
variant: :danger,
dismissible: false,
title: reason) do
.gl-alert-body
title: reason) do |c|
= c.body do
= s_('The git server, Gitaly, is not available at this time. Please contact your administrator.')

View File

@ -12,8 +12,8 @@
- if hook_log.internal_error_message.present?
= render Pajamas::AlertComponent.new(title: _('Internal error occurred while delivering this webhook.'),
variant: :danger,
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
= _('Error: %{error}') % { error: hook_log.internal_error_message }
%h4= _('Response')

View File

@ -8,8 +8,8 @@
- if @conflict
= render Pajamas::AlertComponent.new(variant: :danger,
dismissible: false,
alert_class: 'gl-mb-5') do
.gl-alert-body
alert_class: 'gl-mb-5') do |c|
= c.body do
Someone edited the #{issuable.class.model_name.human.downcase} the same time you did.
Please check out
= link_to "the #{issuable.class.model_name.human.downcase}", polymorphic_path([@project, issuable]), target: "_blank", rel: 'noopener noreferrer'

View File

@ -3,6 +3,6 @@
- if milestone.complete? && milestone.active?
= render Pajamas::AlertComponent.new(variant: :success,
alert_data: { testid: 'all-issues-closed-alert' },
dismissible: false) do
.gl-alert-body
= yield
dismissible: false) do |c|
= c.body do
= yield

View File

@ -3,14 +3,14 @@
- if runner.group_type?
= render Pajamas::AlertComponent.new(alert_class: alert_class,
title: s_('Runners|This runner is available to all projects and subgroups in a group.'),
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
= s_('Runners|Use Group runners when you want all projects in a group to have access to a set of runners.')
= link_to _('Learn more.'), help_page_path('ci/runners/runners_scope', anchor: 'group-runners'), target: '_blank', rel: 'noopener noreferrer'
- else
= render Pajamas::AlertComponent.new(alert_class: alert_class,
title: s_('Runners|This runner is associated with specific projects.'),
dismissible: false) do
.gl-alert-body
dismissible: false) do |c|
= c.body do
= s_('Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner.')
= link_to _('Learn more.'), help_page_path('ci/runners/runners_scope', anchor: 'specific-runners'), target: '_blank', rel: 'noopener noreferrer'

View File

@ -11,13 +11,13 @@
support_link_start: link_start % { url: support_path },
support_link_end: link_end }
= render Pajamas::AlertComponent.new(title: s_('Webhooks|Webhook was automatically disabled'),
variant: :danger) do
.gl-alert-body
variant: :danger) do |c|
= c.body do
= s_('Webhooks|The webhook was triggered more than %{limit} times per minute and is now disabled. To re-enable this webhook, fix the problems shown in %{strong_start}Recent events%{strong_end}, then re-test your settings. %{support_link_start}Contact Support%{support_link_end} if you need help re-enabling your webhook.').html_safe % placeholders
- elsif hook.permanently_disabled?
= render Pajamas::AlertComponent.new(title: s_('Webhooks|Webhook failed to connect'),
variant: :danger) do
.gl-alert-body
variant: :danger) do |c|
= c.body do
= s_('Webhooks|The webhook failed to connect, and is disabled. To re-enable it, check %{strong_start}Recent events%{strong_end} for error details, then test your settings below.').html_safe % { strong_start: strong_start, strong_end: strong_end }
- elsif hook.temporarily_disabled?
- help_path = help_page_path('user/project/integrations/webhooks', anchor: 'webhook-fails-or-multiple-webhook-requests-are-triggered')
@ -27,6 +27,6 @@
help_link_start: link_start % { url: help_path },
help_link_end: link_end }
= render Pajamas::AlertComponent.new(title: s_('Webhooks|Webhook fails to connect'),
variant: :warning) do
.gl-alert-body
variant: :warning) do |c|
= c.body do
= s_('Webhooks|The webhook %{help_link_start}failed to connect%{help_link_end}, and will retry in %{retry_time}. To re-enable it, check %{strong_start}Recent events%{strong_end} for error details, then test your settings below.').html_safe % placeholders

View File

@ -1,8 +0,0 @@
---
name: vulnerability_reads_table
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76220
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348151
milestone: '14.9'
type: development
group: group::threat insights
default_enabled: true

View File

@ -6,7 +6,6 @@ feature_categories:
- continuous_integration
- integrations
- metrics
- pages
- service_ping
- source_code_management
description: GitLab application settings

View File

@ -3,7 +3,7 @@ table_name: award_emoji
classes:
- AwardEmoji
feature_categories:
- snippets
description: TODO
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/3bdc57f0a710b3769381ecad7ea4098223ecff56
- team_planning
description: Store the awarding of emoji by users on Issues, Epics, and other Awardables.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/3785
milestone: '8.9'

View File

@ -4,6 +4,6 @@ classes:
- GroupWikiRepository
feature_categories:
- wiki
description: TODO
description: Stores information about group wiki repositories.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31121
milestone: '13.0'

View File

@ -4,6 +4,6 @@ classes:
- Geo::PagesDeploymentState
feature_categories:
- pages
description: TODO
description: Stores verification state for Geo replicated Pages deployments.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74905
milestone: '14.6'

View File

@ -4,6 +4,6 @@ classes:
- PagesDeployment
feature_categories:
- pages
description: TODO
description: Stores ZIP archives for GitLab Pages websites.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41785
milestone: '13.4'

View File

@ -4,6 +4,6 @@ classes:
- PagesDomainAcmeOrder
feature_categories:
- pages
description: TODO
description: Stores ACME order information used in obtaining Let's Encrypt certificates for GitLab Pages domains.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/14014
milestone: '12.0'

View File

@ -4,6 +4,6 @@ classes:
- PagesDomain
feature_categories:
- pages
description: TODO
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/807a5494fa543392ea7a996b479e577d41ff6344
description: Store Pages domain, certificate and encryption meta data.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/173
milestone: '8.5'

View File

@ -4,6 +4,6 @@ classes:
- ProjectPagesMetadatum
feature_categories:
- pages
description: TODO
description: Store GitLab Pages metadata for projects.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17197
milestone: '12.4'

View File

@ -4,6 +4,6 @@ classes:
- SnippetRepository
feature_categories:
- snippets
description: TODO
description: Stores repository information used to version control snippets.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23796
milestone: '12.8'

View File

@ -4,6 +4,6 @@ classes:
- SnippetStatistics
feature_categories:
- snippets
description: TODO
description: Stores the repository size, commit count, and file count regarding the snippet repository.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35026
milestone: '13.2'

View File

@ -4,6 +4,6 @@ classes:
- SnippetUserMention
feature_categories:
- snippets
description: TODO
description: For storing mentioned users, groups, projects referenced in a snippet description.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19009
milestone: '12.6'

View File

@ -6,6 +6,6 @@ classes:
- Snippet
feature_categories:
- snippets
description: TODO
description: GitLab snippets allow you to store and share bits of code and text with other users.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9265de3d25715aeafd38a4ef41596dca058dc18c
milestone: "<6.0"
milestone: "1.0.1"

View File

@ -3,7 +3,7 @@ table_name: user_agent_details
classes:
- UserAgentDetail
feature_categories:
- snippets
description: TODO
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/95419679f23f0628d1885dd9656cc159e9d55ea9
- instance_resiliency
description: Stores user agent details for submission to Akismet spam detection.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5538
milestone: '8.11'

View File

@ -4,6 +4,6 @@ classes:
- WikiPage::Meta
feature_categories:
- wiki
description: TODO
description: Used to record the metadata for wiki pages when we create events.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26529
milestone: '13.0'

View File

@ -4,6 +4,6 @@ classes:
- WikiPage::Slug
feature_categories:
- wiki
description: TODO
description: Stores wiki page slug metadata for when we create events.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26529
milestone: '13.0'

View File

@ -817,6 +817,138 @@ repository. In the example above:
You can observe the behavior of this queue using the Gitaly logs and Prometheus. For more
information, see the [relevant documentation](monitoring.md#monitor-gitaly-concurrency-limiting).
## Control groups
> - Introduced in GitLab 13.10.
> - New version of the configuration was introduced in GitLab 15.0.
Gitaly shells out to Git for many of its operations. Git can consume a lot of resources for certain operations,
especially for large repositories.
Control groups (cgroups) in Linux allow limits to be imposed on how much memory and CPU can be consumed.
See the [`cgroups` Linux man page](https://man7.org/linux/man-pages/man7/cgroups.7.html) for more information.
cgroups can be useful for protecting the system against resource exhaustion because of overcomsumption of memory and CPU.
Gitaly has built-in cgroups control. When configured, Gitaly assigns Git
processes to a cgroup based on the repository the Git command is operating in.
Each cgroup has a memory and CPU limit. When a cgroup reaches its:
- Memory limit, the kernel looks through the processes for a candidate to kill.
- CPU limit, processes are not killed, but the processes are prevented from consuming more CPU than allowed.
The main reason to configure cgroups for your GitLab installation is that it
protects against system resource starvation due to a few large repositories or
bad actors.
Some Git operations are expensive by nature. `git clone`, for instance,
spawns a `git-upload-pack` process on the server that can consume a lot of memory
for large repositories. For example, a client that keeps on cloning a
large repository over and over again. This situation could potentially use up all of the
memory on a server, causing other operations to fail for other users.
There are many ways someone can create a repository that can consume large amounts of memory when cloned or downloaded.
Using cgroups allows the kernel to kill these operations before they hog up all system resources.
### Configure cgroups in Gitaly
How you configure cgroups in Gitaly depends on what version of GitLab you use.
#### GitLab 13.10 to GitLab 14.10
To configure cgroups in Gitaly for GitLab versions 13.10 to 14.10, add `gitaly['cgroups']` to `/etc/gitlab/gitlab.rb`. For
example:
```ruby
# in /etc/gitlab/gitlab.rb
gitaly['cgroups_count'] = 1000
gitaly['cgroups_mountpoint'] = "/sys/fs/cgroup"
gitaly['cgroups_hierarchy_root'] = "gitaly"
gitaly['cgroups_memory_limit'] = 32212254720
gitaly['cgroups_memory_enabled'] = true
gitaly['cgroups_cpu_shares'] = 1024
gitaly['cgroups_cpu_enabled'] = true
```
- `cgroups_count` is the number of cgroups created. Each time a new
command is spawned, Gitaly assigns it to one of these cgroups based
on the command line arguments of the command. A circular hashing algorithm assigns
commands to these cgroups.
- `cgroups_mountpoint` is where the parent cgroup directory is mounted. Defaults to `/sys/fs/cgroup`.
- `cgroups_hierarchy_root` is the parent cgroup under which Gitaly creates groups, and
is expected to be owned by the user and group Gitaly runs as. Omnibus GitLab
creates the set of directories `mountpoint/<cpu|memory>/hierarchy_root`
when Gitaly starts.
- `cgroups_memory_enabled` enables or disables the memory limit on cgroups.
- `cgroups_memory_bytes` is the total memory limit each cgroup imposes on the processes added to it.
- `cgroups_cpu_enabled` enables or disables the CPU limit on cgroups.
- `cgroups_cpu_shares` is the CPU limit each cgroup imposes on the processes added to it. The maximum is 1024 shares,
which represents 100% of CPU.
which represents 100% of CPU.
#### GitLab 15.0 and later
To configure cgroups in Gitaly for GitLab versions 15.0 and later, add `gitaly['cgroups']` to `/etc/gitlab/gitlab.rb`. For
example:
```ruby
# in /etc/gitlab/gitlab.rb
gitaly['cgroups_mountpoint'] = "/sys/fs/cgroup"
gitaly['cgroups_hierarchy_root'] =>"gitaly"
gitaly['cgroups_memory_bytes'] = 64424509440, # 60gb
gitaly['cgroups_cpu_shares'] = 1024
gitaly['cgroups_repositories_count'] => 1000,
gitaly['cgroups_repositories_memory_bytes'] => 32212254720 # 20gb
gitaly['cgroups_repositories_cpu_shares'] => 512
```
- `cgroups_mountpoint` is where the parent cgroup directory is mounted. Defaults to `/sys/fs/cgroup`.
- `cgroups_hierarchy_root` is the parent cgroup under which Gitaly creates groups, and
is expected to be owned by the user and group Gitaly runs as. Omnibus GitLab
creates the set of directories `mountpoint/<cpu|memory>/hierarchy_root`
when Gitaly starts.
- `cgroups_memory_bytes` is the total memory limit that is imposed collectively on all
Git processes that Gitaly spawns. 0 implies no limit.
- `cgroups_cpu_shares` is the cpu limit that is imposed collectively on all Git
processes that Gitaly spawns. 0 implies no limit. The maximum is 1024 shares,
which represents 100% of CPU.
- `cgroups_repositories_count` is the number of cgroups in the cgroups pool. Each time a new Git
command is spawned, Gitaly assigns it to one of these cgroups based
on the repository the command is for. A circular hashing algorithm assigns
Git commands to these cgroups, so a Git command for a repository is
always assigned to the same cgroup.
- `cgroups_repositories_memory_bytes` is the total memory limit that is imposed collectively on all
Git processes that Gitaly spawns. 0 implies no limit. This value cannot exceed
that of the top level `cgroups_memory_bytes`.
- `cgroups_repositories_cpu_shares` is the CPU limit that is imposed collectively on all Git
processes Gitaly spawns. 0 implies no limit. The maximum is 1024 shares,
which represents 100% of CPU. This value cannot exceed that of the top
level`cgroups_cpu_shares`.
The difference in the cgroups configuration in GitLab 15.0 and later is that we create a pool of cgroups that are isolated
based on the repository used in the Git command to be placed under one of these cgroups.
### Configuring oversubscription
In the previous example configuration for GitLab 15.0 and later:
- The top level memory limit is capped at 60gb.
- Each of the 1000 cgroups in the repositories pool is capped at 20gb.
This is called "oversubscription". Each cgroup in the pool has a much larger capacity than 1/1000th
of the top-level memory limit.
This strategy has two main benefits:
- It gives the host protection from overall memory starvation (OOM), because the top-level
cgroup's memory limit can be set to a threshold smaller than the host's
capacity. Processes outside of that cgroup are not at risk of OOM.
- It allows each individual cgroup in the pool to burst up to a generous upper
bound (in this example 20 GB) that is smaller than the parent cgroup's limit,
but substantially larger than 1/N of the parent's limit. In this example, up
to 3 child cgroups can concurrently burst up to their max. In general, all
1000 cgroups would use much less than the 20 GB.
## Background Repository Optimization
Empty directories and unneeded configuration settings may accumulate in a repository and

View File

@ -44,6 +44,17 @@ the Gitaly logs and Prometheus:
- `gitaly_concurrency_limiting_acquiring_seconds` indicates how long a request has to
wait due to concurrency limits before being processed.
## Monitor Gitaly cgroups
You can observe the status of [control groups (cgroups)](configure_gitaly.md#control-groups) using Prometheus:
- `gitaly_cgroups_memory_failed_total`, a gauge for the total number of times
the memory limit has been hit. This number resets each time a server is
restarted.
- `gitaly_cgroups_cpu_usage`, a gauge that measures CPU usage per cgroup.
- `gitaly_cgroup_procs_total`, a gauge that measures the total number of
processes Gitaly has spawned under the control of cgroups.
## `pack-objects` cache
The following [`pack-objects` cache](configure_gitaly.md#pack-objects-cache) metrics are available:

View File

@ -0,0 +1,34 @@
---
stage: Secure
group: Dynamic Analysis
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Exposure of Private Personal Information (PII) to an unauthorized actor (credit card)
## Description
The target application was found to return credit card information in the response. Organizations
found returning such information may be in violation of industry regulations and could face fines.
## Remediation
PII such as credit cards should never be directly returned to the user. The majority of the information should masked except
the last few digits or characters of the identifier. For example, credit card numbers should
only return the last four digits: `****-****-****-1234`. Ensure this masking is done on the server
and only then send the masked data back to the client. Do not rely on client side JavaScript or other methods
to mask these values as the data could still be intercepted or unmasked.
Additionally, credit card information should never be stored un-encrypted in files or databases.
## Details
| ID | Aggregated | CWE | Type | Risk |
|:---|:--------|:--------|:--------|:--------|
| 359.1 | true | 359 | Passive | Medium |
## Links
- [OWASP Top 10 A3 2017 - Sensitive Data Exposure](https://owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure)
- [CWE](https://cwe.mitre.org/data/definitions/359.html)
- [PCI-DSS](https://www.pcisecuritystandards.org/pdfs/pci_fs_data_storage.pdf)

View File

@ -0,0 +1,34 @@
---
stage: Secure
group: Dynamic Analysis
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Exposure of Private Personal Information (PII) to an unauthorized actor (United States social security number)
## Description
The target application was found to return social security number (SSN) information in the response. Organizations
found returning such information may be in violation of (United States) state or federal laws and may face stiff penalties.
## Remediation
PII such as social security numbers should never be directly returned to the user. The majority of the information
should masked except the last few digits or characters of the identifier. For example, social security numbers
only be displayed with the last four digits: `***-**-1234`. Ensure this masking is done on the server
and only then send the masked data back to the client. Do not rely on client side JavaScript or other methods
to mask these values as the data could still be intercepted or unmasked.
Additionally, social security numbers should never be stored un-encrypted in files or databases.
## Details
| ID | Aggregated | CWE | Type | Risk |
|:---|:--------|:--------|:--------|:--------|
| 359.2 | true | 359 | Passive | Medium |
## Links
- [OWASP Top 10 A3 2017 - Sensitive Data Exposure](https://owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure)
- [CWE](https://cwe.mitre.org/data/definitions/359.html)
- [Privacy Act (CMPPA)](https://www.ssa.gov/dataexchange/privacyinfo.html)

View File

@ -18,6 +18,8 @@ The [DAST browser-based crawler](../browser_based.md) provides a number of vulne
| [16.5](16.5.md) | AspNet header exposes version information | Low | Passive |
| [16.6](16.6.md) | AspNetMvc header exposes version information | Low | Passive |
| [200.1](200.1.md) | Exposure of sensitive information to an unauthorized actor (private IP address) | Low | Passive |
| [359.1](359.1.md) | Exposure of Private Personal Information (PII) to an unauthorized actor (credit card) | Medium | Passive |
| [359.2](359.2.md) | Exposure of Private Personal Information (PII) to an unauthorized actor (United States social security number) | Medium | Passive |
| [548.1](548.1.md) | Exposure of information through directory listing | Low | Passive |
| [598.1](598.1.md) | Use of GET request method with sensitive query strings (session ID) | Medium | Passive |
| [598.2](598.2.md) | Use of GET request method with sensitive query strings (password) | Medium | Passive |

View File

@ -238,7 +238,7 @@ See the [official Kubernetes documentation for details](https://kubernetes.io/do
### `kubectl` commands not supported
The commands `kubectl exec`, `kubectl cp`, `kubectl attach`, and `kubectl port-forward` are not supported.
The commands `kubectl exec`, `kubectl cp`, `kubectl attach`, `kubectl run --attach=true` and `kubectl port-forward` are not supported.
Anything that uses these API endpoints does not work, because they use the deprecated
SPDY protocol.
[An issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/346248) to add support for these commands.

View File

@ -16,7 +16,7 @@ module QA
initial_wiki.project.remove_via_api!
end
it 'creates a formatted Wiki page with an image uploaded', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347640' do
it 'creates a formatted Wiki page with an image uploaded', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/361545', type: :investigating }, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347640' do
initial_wiki.visit!
Page::Project::Wiki::Show.perform(&:click_new_page)

View File

@ -2,13 +2,23 @@
require "spec_helper"
RSpec.describe Pajamas::AlertComponent, :aggregate_failures, type: :component do
context 'with content' do
context 'slots' do
let_it_be(:body) { 'Alert body' }
let_it_be(:actions) { 'Alert actions' }
before do
render_inline(described_class.new) { '_content_' }
render_inline described_class.new do |c|
c.body { body }
c.actions { actions }
end
end
it 'has content' do
expect(rendered_component).to have_text('_content_')
it 'renders alert body' do
expect(rendered_component).to have_content(body)
end
it 'renders actions' do
expect(rendered_component).to have_content(actions)
end
end

View File

@ -17,7 +17,7 @@ describe('content_editor/components/bubble_menus/link', () => {
const buildEditor = () => {
tiptapEditor = createTestEditor({ extensions: [Link] });
contentEditor = { resolveLink: jest.fn() };
contentEditor = { resolveUrl: jest.fn() };
eventHub = eventHubFactory();
};
@ -175,7 +175,7 @@ describe('content_editor/components/bubble_menus/link', () => {
linkHrefInput.setValue('https://google.com');
linkTitleInput.setValue('Search Google');
contentEditor.resolveLink.mockResolvedValue('https://google.com');
contentEditor.resolveUrl.mockResolvedValue('https://google.com');
await wrapper.findComponent(GlForm).vm.$emit('submit', createFakeEvent());
});

View File

@ -43,7 +43,7 @@ describe.each`
const buildEditor = () => {
tiptapEditor = createTestEditor({ extensions: [Image, Audio, Video] });
contentEditor = { resolveLink: jest.fn() };
contentEditor = { resolveUrl: jest.fn() };
eventHub = eventHubFactory();
};
@ -82,7 +82,7 @@ describe.each`
.setNodeSelection(4) // select the media
.run();
contentEditor.resolveLink.mockResolvedValue(`/group1/project1/-/wikis/${filePath}`);
contentEditor.resolveUrl.mockResolvedValue(`/group1/project1/-/wikis/${filePath}`);
await emitEditorEvent({ event: 'transaction', tiptapEditor });
@ -180,7 +180,7 @@ describe.each`
mediaAltInput.setValue('gitlab favicon');
mediaTitleInput.setValue('gitlab favicon');
contentEditor.resolveLink.mockResolvedValue('https://gitlab.com/favicon.png');
contentEditor.resolveUrl.mockResolvedValue('https://gitlab.com/favicon.png');
await wrapper.findComponent(GlForm).vm.$emit('submit', createFakeEvent());
});