Skip to content

Commit 20cc1cc

Browse files
authored
Merge branch 'master' into sayomaki-patch
2 parents 47c3b81 + 4924ee4 commit 20cc1cc

File tree

8 files changed

+38
-20
lines changed

8 files changed

+38
-20
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"array-move": "^4.0.0",
4848
"browserfs": "^1.4.3",
4949
"classnames": "^2.3.2",
50+
"dompurify": "^3.1.6",
5051
"flexboxgrid": "^6.3.1",
5152
"flexboxgrid-helpers": "^1.1.3",
5253
"hastscript": "^9.0.0",
@@ -109,6 +110,7 @@
109110
"@testing-library/jest-dom": "^6.0.0",
110111
"@testing-library/react": "^14.0.0",
111112
"@testing-library/user-event": "^14.4.3",
113+
"@types/dompurify": "^3.0.5",
112114
"@types/estree": "^1.0.5",
113115
"@types/gapi": "^0.0.44",
114116
"@types/gapi.auth2": "^0.0.57",

src/commons/Markdown.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Classes } from '@blueprintjs/core';
22
import classNames from 'classnames';
3+
import DOMPurify from 'dompurify';
34
import React from 'react';
45
import { Converter } from 'showdown';
56

@@ -24,7 +25,12 @@ const Markdown: React.FC<Props> = props => {
2425
return (
2526
<div
2627
className={classNames(props.className ? props.className : 'md', Classes.RUNNING_TEXT)}
27-
dangerouslySetInnerHTML={{ __html: converter.makeHtml(props.content) }}
28+
dangerouslySetInnerHTML={{
29+
__html: DOMPurify.sanitize(converter.makeHtml(props.content), {
30+
USE_PROFILES: { html: true },
31+
ADD_ATTR: ['target']
32+
})
33+
}}
2834
/>
2935
);
3036
};

src/commons/__tests__/__snapshots__/Markdown.tsx.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ exports[`Markdown page renders correctly 1`] = `
66
dangerouslySetInnerHTML={
77
Object {
88
"__html": "<p>Welcome to the Source Academy playground!</p>
9-
<p>The book <a href=\\"https://sourceacademy.org/sicpjs/\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\"><em>Structure and Interpretation of Computer Programs, JavaScript Edition</em></a>
10-
uses JavaScript sublanguages that we call <a href=\\"https://docs.sourceacademy.org/\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\"><em>Source</em></a>. You have chosen the sublanguage <a href=\\"https://docs.sourceacademy.org/source_1/\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\"><em>Source §1</em></a>.</p>
11-
<p>In the editor on the left, you can use the <a href=\\"https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\"><em>Ace keyboard shortcuts</em></a>
12-
and also the <a href=\\"https://github.com/source-academy/frontend/wiki/Source-Academy-Keyboard-Shortcuts\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\"><em>Source Academy keyboard shortcuts</em></a>.</p>",
9+
<p>The book <a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://sourceacademy.org/sicpjs/\\"><em>Structure and Interpretation of Computer Programs, JavaScript Edition</em></a>
10+
uses JavaScript sublanguages that we call <a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://docs.sourceacademy.org/\\"><em>Source</em></a>. You have chosen the sublanguage <a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://docs.sourceacademy.org/source_1/\\"><em>Source §1</em></a>.</p>
11+
<p>In the editor on the left, you can use the <a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts\\"><em>Ace keyboard shortcuts</em></a>
12+
and also the <a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://github.com/source-academy/frontend/wiki/Source-Academy-Keyboard-Shortcuts\\"><em>Source Academy keyboard shortcuts</em></a>.</p>",
1313
}
1414
}
1515
/>

src/commons/navigationBar/subcomponents/AcademyNavigationBar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ const getStaffNavlinkInfo = ({
9191
to: `/courses/${courseId}/groundcontrol`,
9292
icon: IconNames.SATELLITE,
9393
text: 'Ground Control',
94-
disabled: !isStaffOrAdmin,
94+
disabled: !isAdmin,
9595
hiddenInBreakpoints: ['xs', 'sm']
9696
},
9797
{

src/commons/navigationBar/subcomponents/__tests__/AcademyNavigationBar.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,8 @@ jest.mock('react-redux', () => ({
1111
const useSelectorMock = useTypedSelector as jest.Mock;
1212

1313
const assessmentTypes = ['Missions', 'Quests', 'Paths', 'Contests', 'Others'];
14-
const staffRoutes = [
15-
'grading',
16-
'groundcontrol',
17-
'sourcereel',
18-
'gamesimulator',
19-
'dashboard',
20-
'teamformation'
21-
];
22-
const adminRoutes = ['adminpanel'];
14+
const staffRoutes = ['grading', 'sourcereel', 'gamesimulator', 'dashboard', 'teamformation'];
15+
const adminRoutes = ['groundcontrol', 'adminpanel'];
2316
const courseId = 0;
2417
const createCoursePath = (path: string) => `/courses/${courseId}/${path}`;
2518

src/commons/navigationBar/subcomponents/__tests__/__snapshots__/AcademyNavigationBar.tsx.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ exports[`MissionControl, GroundControl, Sourcereel, GameSimulator, Dashboard, Te
419419
align="right"
420420
>
421421
<DesktopNavLink
422-
disabled={false}
422+
disabled={true}
423423
hiddenInBreakpoints={
424424
Array [
425425
"xs",

src/pages/academy/academyRoutes.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ const TeamFormationImport = () => import('./teamFormation/subcomponents/TeamForm
8787
const Dashboard = () => import('./dashboard/Dashboard');
8888

8989
const staffRoutes: RouteObject[] = [
90-
{ path: 'groundcontrol', lazy: GroundControl },
9190
{ path: `grading/${gradingRegExp}`, lazy: Grading },
9291
{ path: 'sourcereel', lazy: Sourcereel },
9392
{ path: 'gamesimulator', lazy: GameSimulator },
@@ -107,9 +106,10 @@ const staffRoutes: RouteObject[] = [
107106

108107
const AdminPanel = () => import('./adminPanel/AdminPanel');
109108

110-
const adminRoutes: RouteObject[] = [{ path: 'adminpanel', lazy: AdminPanel }].map(r =>
111-
new GuardedRoute(r).check(s => s.session.role === Role.Admin, notFoundPath).build()
112-
);
109+
const adminRoutes: RouteObject[] = [
110+
{ path: 'groundcontrol', lazy: GroundControl },
111+
{ path: 'adminpanel', lazy: AdminPanel }
112+
].map(r => new GuardedRoute(r).check(s => s.session.role === Role.Admin, notFoundPath).build());
113113

114114
export const getAcademyRoutes = (): RouteObject[] => {
115115
const routes: RouteObject[] = [...getCommonAcademyRoutes(), ...staffRoutes, ...adminRoutes];

yarn.lock

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2936,6 +2936,13 @@
29362936
dependencies:
29372937
"@types/ms" "*"
29382938

2939+
"@types/dompurify@^3.0.5":
2940+
version "3.0.5"
2941+
resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-3.0.5.tgz#02069a2fcb89a163bacf1a788f73cb415dd75cb7"
2942+
integrity sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==
2943+
dependencies:
2944+
"@types/trusted-types" "*"
2945+
29392946
"@types/eslint@^7.29.0 || ^8.4.1":
29402947
version "8.21.1"
29412948
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.21.1.tgz#110b441a210d53ab47795124dbc3e9bb993d1e7c"
@@ -3279,6 +3286,11 @@
32793286
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8"
32803287
integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==
32813288

3289+
"@types/trusted-types@*":
3290+
version "2.0.7"
3291+
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11"
3292+
integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==
3293+
32823294
"@types/trusted-types@^2.0.2":
32833295
version "2.0.3"
32843296
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.3.tgz#a136f83b0758698df454e328759dbd3d44555311"
@@ -5950,6 +5962,11 @@ domhandler@^5.0.2, domhandler@^5.0.3:
59505962
dependencies:
59515963
domelementtype "^2.3.0"
59525964

5965+
dompurify@^3.1.6:
5966+
version "3.1.6"
5967+
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.6.tgz#43c714a94c6a7b8801850f82e756685300a027e2"
5968+
integrity sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==
5969+
59535970
domutils@^1.7.0:
59545971
version "1.7.0"
59555972
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"

0 commit comments

Comments
 (0)