Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
d243a2e6
Commit
d243a2e6
authored
Sep 02, 2020
by
Tristan Read
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Sanitize issue fields
parent
448371a3
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
72 additions
and
42 deletions
+72
-42
app/assets/javascripts/issue_show/utils/parse_data.js
app/assets/javascripts/issue_show/utils/parse_data.js
+6
-1
spec/frontend/issue_show/components/app_spec.js
spec/frontend/issue_show/components/app_spec.js
+8
-27
spec/frontend/issue_show/issue_spec.js
spec/frontend/issue_show/issue_spec.js
+33
-14
spec/frontend/issue_show/mock_data.js
spec/frontend/issue_show/mock_data.js
+25
-0
No files found.
app/assets/javascripts/issue_show/utils/parse_data.js
View file @
d243a2e6
...
@@ -4,7 +4,12 @@ export const parseIssuableData = () => {
...
@@ -4,7 +4,12 @@ export const parseIssuableData = () => {
try
{
try
{
const
initialDataEl
=
document
.
getElementById
(
'
js-issuable-app-initial-data
'
);
const
initialDataEl
=
document
.
getElementById
(
'
js-issuable-app-initial-data
'
);
return
JSON
.
parse
(
sanitize
(
initialDataEl
.
textContent
).
replace
(
/"/g
,
'
"
'
));
const
parsedData
=
JSON
.
parse
(
initialDataEl
.
textContent
.
replace
(
/"/g
,
'
"
'
));
parsedData
.
initialTitleHtml
=
sanitize
(
parsedData
.
initialTitleHtml
);
parsedData
.
initialDescriptionHtml
=
sanitize
(
parsedData
.
initialDescriptionHtml
);
return
parsedData
;
}
catch
(
e
)
{
}
catch
(
e
)
{
console
.
error
(
e
);
// eslint-disable-line no-console
console
.
error
(
e
);
// eslint-disable-line no-console
...
...
spec/frontend/issue_show/components/app_spec.js
View file @
d243a2e6
import
{
GlIntersectionObserver
}
from
'
@gitlab/ui
'
;
import
{
GlIntersectionObserver
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
{
useMockIntersectionObserver
}
from
'
helpers/mock_dom_observer
'
;
import
{
useMockIntersectionObserver
}
from
'
helpers/mock_dom_observer
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
visitUrl
}
from
'
~/lib/utils/url_utility
'
;
import
{
visitUrl
}
from
'
~/lib/utils/url_utility
'
;
import
'
~/behaviors/markdown/render_gfm
'
;
import
'
~/behaviors/markdown/render_gfm
'
;
import
IssuableApp
from
'
~/issue_show/components/app.vue
'
;
import
IssuableApp
from
'
~/issue_show/components/app.vue
'
;
import
eventHub
from
'
~/issue_show/event_hub
'
;
import
eventHub
from
'
~/issue_show/event_hub
'
;
import
{
initialRequest
,
secondRequest
}
from
'
../mock_data
'
;
import
{
appProps
,
initialRequest
,
publishedIncidentUrl
,
secondRequest
,
zoomMeetingUrl
,
}
from
'
../mock_data
'
;
import
IncidentTabs
from
'
~/issue_show/components/incident_tabs.vue
'
;
import
IncidentTabs
from
'
~/issue_show/components/incident_tabs.vue
'
;
import
DescriptionComponent
from
'
~/issue_show/components/description.vue
'
;
import
DescriptionComponent
from
'
~/issue_show/components/description.vue
'
;
import
PinnedLinks
from
'
~/issue_show/components/pinned_links.vue
'
;
import
PinnedLinks
from
'
~/issue_show/components/pinned_links.vue
'
;
...
@@ -22,30 +27,6 @@ jest.mock('~/issue_show/event_hub');
...
@@ -22,30 +27,6 @@ jest.mock('~/issue_show/event_hub');
const
REALTIME_REQUEST_STACK
=
[
initialRequest
,
secondRequest
];
const
REALTIME_REQUEST_STACK
=
[
initialRequest
,
secondRequest
];
const
zoomMeetingUrl
=
'
https://gitlab.zoom.us/j/95919234811
'
;
const
publishedIncidentUrl
=
'
https://status.com/
'
;
const
defaultProps
=
{
canUpdate
:
true
,
canDestroy
:
true
,
endpoint
:
'
/gitlab-org/gitlab-shell/-/issues/9/realtime_changes
'
,
updateEndpoint
:
TEST_HOST
,
issuableRef
:
'
#1
'
,
issuableStatus
:
'
opened
'
,
initialTitleHtml
:
''
,
initialTitleText
:
''
,
initialDescriptionHtml
:
'
test
'
,
initialDescriptionText
:
'
test
'
,
lockVersion
:
1
,
markdownPreviewPath
:
'
/
'
,
markdownDocsPath
:
'
/
'
,
projectNamespace
:
'
/
'
,
projectPath
:
'
/
'
,
issuableTemplateNamesPath
:
'
/issuable-templates-path
'
,
zoomMeetingUrl
,
publishedIncidentUrl
,
};
describe
(
'
Issuable output
'
,
()
=>
{
describe
(
'
Issuable output
'
,
()
=>
{
useMockIntersectionObserver
();
useMockIntersectionObserver
();
...
@@ -57,7 +38,7 @@ describe('Issuable output', () => {
...
@@ -57,7 +38,7 @@ describe('Issuable output', () => {
const
mountComponent
=
(
props
=
{})
=>
{
const
mountComponent
=
(
props
=
{})
=>
{
wrapper
=
mount
(
IssuableApp
,
{
wrapper
=
mount
(
IssuableApp
,
{
propsData
:
{
...
default
Props
,
...
props
},
propsData
:
{
...
app
Props
,
...
props
},
});
});
};
};
...
...
spec/frontend/issue_show/issue_spec.js
View file @
d243a2e6
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
useMockIntersectionObserver
}
from
'
helpers/mock_dom_observer
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
initIssuableApp
from
'
~/issue_show/issue
'
;
import
initIssuableApp
from
'
~/issue_show/issue
'
;
import
{
parseIssuableData
}
from
'
~/issue_show/utils/parse_data
'
;
import
*
as
parseData
from
'
~/issue_show/utils/parse_data
'
;
import
{
appProps
}
from
'
./mock_data
'
;
const
mock
=
new
MockAdapter
(
axios
);
mock
.
onGet
().
reply
(
200
);
useMockIntersectionObserver
();
jest
.
mock
(
'
~/lib/utils/poll
'
);
const
setupHTML
=
initialData
=>
{
document
.
body
.
innerHTML
=
`
<div id="js-issuable-app"></div>
<script id="js-issuable-app-initial-data" type="application/json">
${
JSON
.
stringify
(
initialData
)}
</script>
`
;
};
describe
(
'
Issue show index
'
,
()
=>
{
describe
(
'
Issue show index
'
,
()
=>
{
describe
(
'
initIssueableApp
'
,
()
=>
{
describe
(
'
initIssueableApp
'
,
()
=>
{
// Warning: this test is currently faulty.
it
(
'
should initialize app with no potential XSS attack
'
,
async
()
=>
{
// More details at https://gitlab.com/gitlab-org/gitlab/-/issues/241717
const
alertSpy
=
jest
.
spyOn
(
window
,
'
alert
'
).
mockImplementation
(()
=>
{});
// eslint-disable-next-line jest/no-disabled-tests
const
parseDataSpy
=
jest
.
spyOn
(
parseData
,
'
parseIssuableData
'
);
it
.
skip
(
'
should initialize app with no potential XSS attack
'
,
()
=>
{
const
d
=
document
.
createElement
(
'
div
'
);
d
.
id
=
'
js-issuable-app-initial-data
'
;
d
.
innerHTML
=
JSON
.
stringify
({
initialDescriptionHtml
:
'
<img src=x onerror=alert(1)>
'
,
});
document
.
body
.
appendChild
(
d
);
setupHTML
({
...
appProps
,
initialDescriptionHtml
:
'
<svg onload=window.alert(1)>
'
,
});
const
alertSpy
=
jest
.
spyOn
(
window
,
'
alert
'
);
const
issuableData
=
parseData
.
parseIssuableData
();
const
issuableData
=
parseIssuableData
();
initIssuableApp
(
issuableData
);
initIssuableApp
(
issuableData
);
await
waitForPromises
();
expect
(
parseDataSpy
).
toHaveBeenCalled
();
expect
(
alertSpy
).
not
.
toHaveBeenCalled
();
expect
(
alertSpy
).
not
.
toHaveBeenCalled
();
});
});
});
});
...
...
spec/frontend/issue_show/mock_data.js
View file @
d243a2e6
...
@@ -31,3 +31,28 @@ export const descriptionProps = {
...
@@ -31,3 +31,28 @@ export const descriptionProps = {
taskStatus
:
''
,
taskStatus
:
''
,
updateUrl
:
TEST_HOST
,
updateUrl
:
TEST_HOST
,
};
};
export
const
publishedIncidentUrl
=
'
https://status.com/
'
;
export
const
zoomMeetingUrl
=
'
https://gitlab.zoom.us/j/95919234811
'
;
export
const
appProps
=
{
canUpdate
:
true
,
canDestroy
:
true
,
endpoint
:
'
/gitlab-org/gitlab-shell/-/issues/9/realtime_changes
'
,
updateEndpoint
:
TEST_HOST
,
issuableRef
:
'
#1
'
,
issuableStatus
:
'
opened
'
,
initialTitleHtml
:
''
,
initialTitleText
:
''
,
initialDescriptionHtml
:
'
test
'
,
initialDescriptionText
:
'
test
'
,
lockVersion
:
1
,
markdownPreviewPath
:
'
/
'
,
markdownDocsPath
:
'
/
'
,
projectNamespace
:
'
/
'
,
projectPath
:
'
/
'
,
issuableTemplateNamesPath
:
'
/issuable-templates-path
'
,
zoomMeetingUrl
,
publishedIncidentUrl
,
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment