Commit 3e4abff5 authored by Kev's avatar Kev Committed by Olena Horal-Koretska

Replace v-html with v-safe-html in dismissal_note.vue

parent e52642f4
<script>
/* eslint-disable vue/no-v-html */
import { escape } from 'lodash';
import EventItem from 'ee/vue_shared/security_reports/components/event_item.vue';
import { GlButton } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import { GlButton, GlSprintf, GlLink } from '@gitlab/ui';
import { __ } from '~/locale';
export default {
components: {
EventItem,
GlButton,
GlSprintf,
GlLink,
},
props: {
feedback: {
......@@ -42,33 +42,23 @@ export default {
},
},
computed: {
pipeline() {
return this.feedback?.pipeline;
},
eventText() {
const { project, feedback } = this;
const { pipeline } = feedback;
const pipelineLink =
pipeline && pipeline.path && pipeline.id
? `<a href="${pipeline.path}">#${pipeline.id}</a>`
: null;
const { project, pipeline } = this;
const projectLink =
project && project.url && project.value
? `<a href="${escape(project.url)}">${escape(project.value)}</a>`
: null;
const hasPipeline = Boolean(pipeline?.path && pipeline?.id);
const hasProject = Boolean(project?.url && project?.value);
if (pipelineLink && projectLink) {
return sprintf(
__('Dismissed on pipeline %{pipelineLink} at %{projectLink}'),
{ pipelineLink, projectLink },
false,
);
}
if (pipelineLink && !projectLink) {
return sprintf(__('Dismissed on pipeline %{pipelineLink}'), { pipelineLink }, false);
}
if (!pipelineLink && projectLink) {
return sprintf(__('Dismissed at %{projectLink}'), { projectLink }, false);
if (hasPipeline && hasProject) {
return __('Dismissed on pipeline %{pipelineLink} at %{projectLink}');
} else if (hasPipeline) {
return __('Dismissed on pipeline %{pipelineLink}');
} else if (hasProject) {
return __('Dismissed at %{projectLink}');
}
return __('Dismissed');
},
commentDetails() {
......@@ -100,7 +90,16 @@ export default {
icon-name="cancel"
icon-class="ci-status-icon-pending"
>
<div v-if="feedback.created_at" v-html="eventText"></div>
<div v-if="feedback.created_at">
<gl-sprintf :message="eventText">
<template v-if="pipeline" #pipelineLink>
<gl-link :href="pipeline.path">#{{ pipeline.id }}</gl-link>
</template>
<template v-if="project" #projectLink>
<gl-link :href="project.value">{{ project.value }}</gl-link>
</template>
</gl-sprintf>
</div>
</event-item>
<template v-if="commentDetails && !isCommentingOnDismissal">
<hr class="my-3" />
......
---
title: Replace v-html with v-safe-html in dismissal_note.vue
merge_request: 41137
author: Kev @KevSlashNull
type: other
import { shallowMount, mount } from '@vue/test-utils';
import { GlSprintf } from '@gitlab/ui';
import component from 'ee/vue_shared/security_reports/components/dismissal_note.vue';
import EventItem from 'ee/vue_shared/security_reports/components/event_item.vue';
......@@ -22,7 +23,7 @@ describe('dismissal note', () => {
let wrapper;
const mountComponent = (options, mountFn = shallowMount) => {
wrapper = mountFn(component, options);
wrapper = mountFn(component, { ...options, stubs: { GlSprintf } });
};
describe('with no attached project or pipeline', () => {
......@@ -97,13 +98,8 @@ describe('dismissal note', () => {
});
it('should escape the project name', () => {
// Note: We have to check the computed prop here because
// vue test utils unescapes the result of wrapper.text()
expect(wrapper.vm.eventText).not.toContain(project.value);
expect(wrapper.vm.eventText).toContain(
'Foo &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;',
);
// wrapper.text() is the text string, if the tag was parsed then it would be missing <script> from the string.
expect(wrapper.text()).toContain(unsafeProject.value);
});
});
......
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