From fa11dcc9a23a2ba4b2f502b14218ed85e70c4c9d Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Thu, 8 Aug 2024 09:11:17 +1000 Subject: [PATCH 01/18] Fix for PROD-4375 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 1db5fcba..ed6c1a2f 100644 --- a/package.json +++ b/package.json @@ -38,9 +38,9 @@ "jwt-decode": "^2.2.0", "lodash": "^4.17.11", "mini-css-extract-plugin": "0.4.3", - "moment": "^2.24.0", - "moment-duration-format": "^2.2.2", - "moment-timezone": "^0.5.34", + "moment": "^2.29.4", + "moment-duration-format": "^2.3.2", + "moment-timezone": "^0.5.43", "node-sass": "^4.14.0", "normalize-text": "^2.4.1", "optimize-css-assets-webpack-plugin": "5.0.1", From 46442d7961c34b94ac4465eb6329d9bc1d60f35f Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Thu, 29 Aug 2024 01:11:31 +0000 Subject: [PATCH 02/18] New reminder to use the new app when launching challenges --- .../ChallengeEditor.module.scss | 19 +++++++++++++++++++ src/components/ChallengeEditor/index.js | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/src/components/ChallengeEditor/ChallengeEditor.module.scss b/src/components/ChallengeEditor/ChallengeEditor.module.scss index 80989102..053b65ec 100644 --- a/src/components/ChallengeEditor/ChallengeEditor.module.scss +++ b/src/components/ChallengeEditor/ChallengeEditor.module.scss @@ -459,3 +459,22 @@ ul.linkList { content:',\0000a0'; /* Non-breaking space */ } } + +.newPlatformWarning{ + text-align: center; + background-color: rgb(204, 65, 65); + padding: 20px; + max-width: 600px; + border-radius: 6px; + margin-bottom: 10px; + + a { + color: white; + text-decoration: underline; + } +} + +.warningHeader{ + font-weight: bold; + font-size: 1.2rem; +} \ No newline at end of file diff --git a/src/components/ChallengeEditor/index.js b/src/components/ChallengeEditor/index.js index 0ce1ea9a..0b428159 100644 --- a/src/components/ChallengeEditor/index.js +++ b/src/components/ChallengeEditor/index.js @@ -1641,6 +1641,8 @@ class ChallengeEditor extends Component { const currentChallengeId = this.getCurrentChallengeId() const showTimeline = false // disables the timeline for time being https://github.com/topcoder-platform/challenge-engine-ui/issues/706 const copilotResources = metadata.members || challengeResources + console.log(`Members: ${JSON.stringify(metadata.members, null, 5)}`) + console.log(`challengeResources: ${JSON.stringify(challengeResources, null, 5)}`) const isDesignChallenge = challenge.trackId === DES_TRACK_ID const isDevChallenge = challenge.trackId === DEV_TRACK_ID const isMM = challenge.typeId === MARATHON_TYPE_ID @@ -1660,6 +1662,10 @@ class ChallengeEditor extends Component { const challengeForm = isNew ? (
+
+ Please use the new platform
+ If you are launching a challenge that is not a Marathon Match or Innovation Challenge, please use the new app platform here +
From 38e5efd49349bacd969b67f0a6e8da894cb2f0df Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Fri, 8 Nov 2024 06:56:55 +1100 Subject: [PATCH 03/18] Revert "New reminder to use the new app when launching challenges" This reverts commit 46442d7961c34b94ac4465eb6329d9bc1d60f35f. --- .../ChallengeEditor.module.scss | 19 ------------------- src/components/ChallengeEditor/index.js | 6 ------ 2 files changed, 25 deletions(-) diff --git a/src/components/ChallengeEditor/ChallengeEditor.module.scss b/src/components/ChallengeEditor/ChallengeEditor.module.scss index 053b65ec..80989102 100644 --- a/src/components/ChallengeEditor/ChallengeEditor.module.scss +++ b/src/components/ChallengeEditor/ChallengeEditor.module.scss @@ -459,22 +459,3 @@ ul.linkList { content:',\0000a0'; /* Non-breaking space */ } } - -.newPlatformWarning{ - text-align: center; - background-color: rgb(204, 65, 65); - padding: 20px; - max-width: 600px; - border-radius: 6px; - margin-bottom: 10px; - - a { - color: white; - text-decoration: underline; - } -} - -.warningHeader{ - font-weight: bold; - font-size: 1.2rem; -} \ No newline at end of file diff --git a/src/components/ChallengeEditor/index.js b/src/components/ChallengeEditor/index.js index 0b428159..0ce1ea9a 100644 --- a/src/components/ChallengeEditor/index.js +++ b/src/components/ChallengeEditor/index.js @@ -1641,8 +1641,6 @@ class ChallengeEditor extends Component { const currentChallengeId = this.getCurrentChallengeId() const showTimeline = false // disables the timeline for time being https://github.com/topcoder-platform/challenge-engine-ui/issues/706 const copilotResources = metadata.members || challengeResources - console.log(`Members: ${JSON.stringify(metadata.members, null, 5)}`) - console.log(`challengeResources: ${JSON.stringify(challengeResources, null, 5)}`) const isDesignChallenge = challenge.trackId === DES_TRACK_ID const isDevChallenge = challenge.trackId === DEV_TRACK_ID const isMM = challenge.typeId === MARATHON_TYPE_ID @@ -1662,10 +1660,6 @@ class ChallengeEditor extends Component { const challengeForm = isNew ? ( -
- Please use the new platform
- If you are launching a challenge that is not a Marathon Match or Innovation Challenge, please use the new app platform here -
From 67f995d37047173006b0d253c0967dcbad694dfa Mon Sep 17 00:00:00 2001 From: Kiril Kartunov Date: Tue, 10 Dec 2024 10:43:32 +0200 Subject: [PATCH 04/18] PM-216 clean up injection in test script --- scripts/test.js | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/scripts/test.js b/scripts/test.js index 9c17521c..520c3464 100644 --- a/scripts/test.js +++ b/scripts/test.js @@ -16,27 +16,8 @@ process.on('unhandledRejection', err => { require('../config/env') const jest = require('jest') -const execSync = require('child_process').execSync let argv = process.argv.slice(2) -function isInGitRepository () { - try { - execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' }) - return true - } catch (e) { - return false - } -} - -function isInMercurialRepository () { - try { - execSync('hg --cwd . root', { stdio: 'ignore' }) - return true - } catch (e) { - return false - } -} - // Watch unless on CI, in coverage mode, or explicitly running all tests if ( !process.env.CI && @@ -44,8 +25,7 @@ if ( argv.indexOf('--watchAll') === -1 ) { // https://github.com/facebook/create-react-app/issues/5210 - const hasSourceControl = isInGitRepository() || isInMercurialRepository() - argv.push(hasSourceControl ? '--watch' : '--watchAll') + argv.push('--watchAll') } jest.run(argv) From a3c36749944299bc6c051819d042fc018068c5c4 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Tue, 10 Dec 2024 15:16:12 +0100 Subject: [PATCH 05/18] fix: removed cookie file and started using local storage instead of cookie --- .../ChallengeEditor/ChallengeView/index.js | 2 +- src/components/ChallengeEditor/index.js | 2 +- src/routes.js | 6 +- src/util/cookie.js | 34 ----------- src/util/localstorage.js | 61 +++++++++++++++++++ 5 files changed, 66 insertions(+), 39 deletions(-) delete mode 100644 src/util/cookie.js create mode 100644 src/util/localstorage.js diff --git a/src/components/ChallengeEditor/ChallengeView/index.js b/src/components/ChallengeEditor/ChallengeView/index.js index c2da57eb..a8e45389 100644 --- a/src/components/ChallengeEditor/ChallengeView/index.js +++ b/src/components/ChallengeEditor/ChallengeView/index.js @@ -18,7 +18,6 @@ import ChallengeTotalField from '../ChallengeTotal-Field' import Loader from '../../Loader' import AssignedMemberField from '../AssignedMember-Field' import { getResourceRoleByName } from '../../../util/tc' -import { isBetaMode } from '../../../util/cookie' import { loadGroupDetails } from '../../../actions/challenges' import { REVIEW_TYPES, @@ -29,6 +28,7 @@ import { } from '../../../config/constants' import PhaseInput from '../../PhaseInput' import CheckpointPrizesField from '../CheckpointPrizes-Field' +import { isBetaMode } from '../../../util/localstorage' const ChallengeView = ({ projectDetail, diff --git a/src/components/ChallengeEditor/index.js b/src/components/ChallengeEditor/index.js index 0ce1ea9a..03579485 100644 --- a/src/components/ChallengeEditor/index.js +++ b/src/components/ChallengeEditor/index.js @@ -69,11 +69,11 @@ import Tooltip from '../Tooltip' import CancelDropDown from './Cancel-Dropdown' import UseSchedulingAPIField from './UseSchedulingAPIField' -import { isBetaMode } from '../../util/cookie' import MilestoneField from './Milestone-Field' import DiscussionField from './Discussion-Field' import CheckpointPrizesField from './CheckpointPrizes-Field' import { canChangeDuration } from '../../util/phase' +import { isBetaMode } from '../../util/localstorage' const theme = { container: styles.modalContainer diff --git a/src/routes.js b/src/routes.js index 34e995da..f4ca4487 100644 --- a/src/routes.js +++ b/src/routes.js @@ -17,11 +17,11 @@ import { saveToken } from './actions/auth' import { loadChallengeDetails } from './actions/challenges' import { connect } from 'react-redux' import { checkAllowedRoles, checkOnlyReadOnlyRoles, checkReadOnlyRoles } from './util/tc' -import { setCookie, removeCookie, isBetaMode } from './util/cookie' import IdleTimer from 'react-idle-timer' import modalStyles from './styles/modal.module.scss' import ConfirmationModal from './components/Modal/ConfirmationModal' import Users from './containers/Users' +import { isBetaMode, removeFromLocalStorage, saveToLocalStorage } from './util/localstorage' const { ACCOUNTS_APP_LOGIN_URL, IDLE_TIMEOUT_MINUTES, IDLE_TIMEOUT_GRACE_MINUTES, COMMUNITY_APP_URL } = process.env @@ -105,9 +105,9 @@ class Routes extends React.Component { const params = new URLSearchParams(search) if (!_.isEmpty(params.get('beta'))) { if (params.get('beta') === 'true' && !isBetaMode()) { - setCookie(BETA_MODE_COOKIE_TAG, 'true') + saveToLocalStorage(BETA_MODE_COOKIE_TAG, 'true') } else if (params.get('beta') === 'false' && isBetaMode()) { - removeCookie(BETA_MODE_COOKIE_TAG) + removeFromLocalStorage(BETA_MODE_COOKIE_TAG) } this.props.history.push(this.props.location.pathname) } diff --git a/src/util/cookie.js b/src/util/cookie.js deleted file mode 100644 index b1242acb..00000000 --- a/src/util/cookie.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Provides Cookie related utility methods - */ - -import { BETA_MODE_COOKIE_TAG } from '../config/constants' - -/** - * A function that get's a cookie - */ -export function getCookie (name) { - const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)') - return v ? v[2] : undefined -} - -/** - * A function that set's a cookie - */ -export function setCookie (name, value) { - document.cookie = `${name}=${value}; path=/` -} - -/** - * A function that removes Cookie by setting expiry date to past - */ -export function removeCookie (name) { - document.cookie = `${name}=; path=/; expires=Thu, 18 Dec 2013 12:00:00 UTC;` -} - -/** - * A function that checks whether beta mode is enabled or not - */ -export function isBetaMode () { - return getCookie(BETA_MODE_COOKIE_TAG) -} diff --git a/src/util/localstorage.js b/src/util/localstorage.js new file mode 100644 index 00000000..b835645f --- /dev/null +++ b/src/util/localstorage.js @@ -0,0 +1,61 @@ +import { BETA_MODE_COOKIE_TAG } from '../config/constants' + +/** + * Save an item to localStorage. + * @param {string} key - The key under which the data will be stored. + * @param {any} value - The data to store (will be stringified). + */ +export function saveToLocalStorage (key, value) { + if (!key || typeof key !== 'string') { + throw new Error('Key must be a valid string.') + } + + try { + const jsonValue = JSON.stringify(value) + window.localStorage.setItem(key, jsonValue) + } catch (error) { + console.error('Failed to save to localStorage:', error) + } +} + +/** +* Get an item from localStorage. +* @param {string} key - The key under which the data is stored. +* @returns {any} - The parsed data from localStorage, or null if not found. +*/ +export function getFromLocalStorage (key) { + if (!key || typeof key !== 'string') { + throw new Error('Key must be a valid string.') + } + + try { + const jsonValue = window.localStorage.getItem(key) + return jsonValue ? JSON.parse(jsonValue) : null + } catch (error) { + console.error('Failed to retrieve from localStorage:', error) + return null + } +} + +/** + * Remove an item from localStorage. + * @param {string} key - The key of the item to remove. + */ +export function removeFromLocalStorage (key) { + if (!key || typeof key !== 'string') { + throw new Error('Key must be a valid string.') + } + + try { + window.localStorage.removeItem(key) + } catch (error) { + console.error('Failed to remove from localStorage:', error) + } +} + +/** + * A function that checks whether beta mode is enabled or not + */ +export function isBetaMode () { + return getFromLocalStorage(BETA_MODE_COOKIE_TAG) +} From 8f1339be00e50e8743a19dfb87f2a5c0f14a6dda Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Tue, 10 Dec 2024 15:20:59 +0100 Subject: [PATCH 06/18] fix: removed cookie file and started using local storage instead of cookie --- src/util/localstorage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/localstorage.js b/src/util/localstorage.js index b835645f..00fcd6d4 100644 --- a/src/util/localstorage.js +++ b/src/util/localstorage.js @@ -57,5 +57,5 @@ export function removeFromLocalStorage (key) { * A function that checks whether beta mode is enabled or not */ export function isBetaMode () { - return getFromLocalStorage(BETA_MODE_COOKIE_TAG) + return getFromLocalStorage(BETA_MODE_COOKIE_TAG) === 'true' } From 2f0eb77c080c96d7ba12402ea6355ea368871f1d Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Tue, 10 Dec 2024 21:57:48 +0100 Subject: [PATCH 07/18] fix: default user privilege --- docker/Dockerfile | 4 ++++ test-automation/Dockerfile | 3 +++ 2 files changed, 7 insertions(+) diff --git a/docker/Dockerfile b/docker/Dockerfile index 496381d5..8eaf11db 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,6 @@ # Use the base image with Node.js FROM node:12 +RUN useradd -m -s /bin/bash appuser ARG NODE_ENV ARG BABEL_ENV @@ -18,6 +19,9 @@ COPY . /challenge-engine-ui # Set working directory for future use WORKDIR /challenge-engine-ui +RUN chown -R appuser:appuser /challenge-engine-ui +USER appuser + # Install the dependencies from package.json RUN echo "NODE ENV in Docker: $NODE_ENV" RUN echo "BABEL ENV in Docker: $BABEL_ENV" diff --git a/test-automation/Dockerfile b/test-automation/Dockerfile index 2f5a74ed..843a120a 100644 --- a/test-automation/Dockerfile +++ b/test-automation/Dockerfile @@ -1,4 +1,5 @@ FROM node:10.17.0-stretch +RUN useradd -m -s /bin/bash appuser RUN apt update RUN apt install sudo RUN sudo apt-get update; sudo apt-get install -y openjdk-8-jre openjdk-8-jre-headless openjdk-8-jdk openjdk-8-jdk-headless; @@ -26,6 +27,8 @@ RUN printf '#!/bin/sh\nXvfb :99 -screen 0 1280x1024x24 &\nexec "$@"\n' > /tmp/en COPY . /test-automation WORKDIR /test-automation +RUN chown -R appuser:appuser /test-automation +USER appuser RUN npm install RUN ./node_modules/.bin/webdriver-manager update --versions.chrome=="$(google-chrome -version)" ENTRYPOINT ["/docker-entrypoint.sh"] From 86961da6682c8a97ce006b704f046059713bc494 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Wed, 11 Dec 2024 20:11:15 +0100 Subject: [PATCH 08/18] fix: removed password from config json --- test-automation/config/config.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/test-automation/config/config.json b/test-automation/config/config.json index 7ec0216c..744e51e5 100644 --- a/test-automation/config/config.json +++ b/test-automation/config/config.json @@ -1,12 +1,10 @@ { "copilotRole": { "email": "topcoderconnect+Copilot@gmail.com", - "password": "appirio123", "handle": "TCConnCopilot" }, "copilotManagerRole": { "email": "topcoderconnect+CopilotManager@gmail.com", - "password": "appirio123", "handle": "TCConCopilotMgr" }, "givenUrl": "https://challenges.topcoder-dev.com/", From 0276a775957fc359e64816f3fe35d3f132c862d0 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Thu, 12 Dec 2024 10:44:19 +0200 Subject: [PATCH 09/18] PM-222 - tackle SAST/open-redirect: remove deprecated segment integration --- src/config/constants.js | 1 - src/index.js | 11 +---------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/config/constants.js b/src/config/constants.js index 8542258a..b8917e2a 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -19,7 +19,6 @@ export const { CP_TRACK_ID, CHALLENGE_TYPE_ID, MARATHON_TYPE_ID, - SEGMENT_API_KEY, MULTI_ROUND_CHALLENGE_TEMPLATE_ID, UNIVERSAL_NAV_URL, HEADER_AUTH_URLS_HREF, diff --git a/src/index.js b/src/index.js index 82fb6376..180e6126 100644 --- a/src/index.js +++ b/src/index.js @@ -6,19 +6,10 @@ import ReactDOM from 'react-dom' import './styles/main.scss' import 'react-redux-toastr/lib/css/react-redux-toastr.min.css' import App from './App' -import { SEGMENT_API_KEY, UNIVERSAL_NAV_URL } from './config/constants' +import { UNIVERSAL_NAV_URL } from './config/constants' ReactDOM.render(, document.getElementById('root')) -/* eslint-disable */ -if (!_.isEmpty(SEGMENT_API_KEY)) { - !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e // eslint-disable-next-line no-unused-expressions !(function (n, t, e, a, c, i, o) { From bbe2de2d89dc04ee67b81af67c53a0d6b03e9399 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Thu, 12 Dec 2024 10:55:11 +0200 Subject: [PATCH 10/18] PM-222 - tackle SAST/open-redirect: ensure uninav domain is as expected --- src/index.js | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/index.js b/src/index.js index 180e6126..f822b9ba 100644 --- a/src/index.js +++ b/src/index.js @@ -11,27 +11,30 @@ import { UNIVERSAL_NAV_URL } from './config/constants' ReactDOM.render(, document.getElementById('root')) // -// eslint-disable-next-line no-unused-expressions -!(function (n, t, e, a, c, i, o) { -// eslint-disable-next-line no-unused-expressions, no-sequences - ;(n['TcUnivNavConfig'] = c), - (n[c] = - n[c] || - function () { - ;(n[c].q = n[c].q || []).push(arguments) - }), - (n[c].l = 1 * new Date()) +// SAST/open-redirect handling: make sure script hostname matches what we expect +if ((new URL(UNIVERSAL_NAV_URL)).hostname.match(/uni-nav.topcoder(-dev)?.com$/i)) { + // eslint-disable-next-line no-unused-expressions + !(function (n, t, e, a, c, i, o) { // eslint-disable-next-line no-unused-expressions, no-sequences - ;(i = t.createElement(e)), (o = t.getElementsByTagName(e)[0]) - i.async = 1 - i.type = 'module' - i.src = a - o.parentNode.insertBefore(i, o) -})( - window, - document, - 'script', - UNIVERSAL_NAV_URL, - 'tcUniNav' -) + ;(n['TcUnivNavConfig'] = c), + (n[c] = + n[c] || + function () { + ;(n[c].q = n[c].q || []).push(arguments) + }), + (n[c].l = 1 * new Date()) + // eslint-disable-next-line no-unused-expressions, no-sequences + ;(i = t.createElement(e)), (o = t.getElementsByTagName(e)[0]) + i.async = 1 + i.type = 'module' + i.src = a + o.parentNode.insertBefore(i, o) + })( + window, + document, + 'script', + UNIVERSAL_NAV_URL, + 'tcUniNav' + ) +} // From e12f3ba87e6d09057591652a6702632ea150e0df Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Thu, 12 Dec 2024 19:34:27 +0530 Subject: [PATCH 11/18] PM-226 Replace dangerouslySetInnerHtml with plaintext rendering --- src/components/ChallengeEditor/ChallengeView/index.js | 6 +----- src/components/ChallengeEditor/index.js | 7 +------ src/components/ChallengesComponent/index.js | 10 +++------- src/components/ProjectCard/index.js | 3 +-- 4 files changed, 6 insertions(+), 20 deletions(-) diff --git a/src/components/ChallengeEditor/ChallengeView/index.js b/src/components/ChallengeEditor/ChallengeView/index.js index c2da57eb..a16bd8a2 100644 --- a/src/components/ChallengeEditor/ChallengeView/index.js +++ b/src/components/ChallengeEditor/ChallengeView/index.js @@ -4,7 +4,6 @@ import PropTypes from 'prop-types' import cn from 'classnames' import { withRouter } from 'react-router-dom' import styles from './ChallengeView.module.scss' -import xss from 'xss' import Track from '../../Track' import NDAField from '../NDAField' import UseSchedulingAPIField from '../UseSchedulingAPIField' @@ -114,10 +113,7 @@ const ChallengeView = ({
- Project: - + Project: {projectDetail ? projectDetail.name : ''}
{selectedMilestone && diff --git a/src/components/ChallengeEditor/index.js b/src/components/ChallengeEditor/index.js index 0ce1ea9a..eaa1de82 100644 --- a/src/components/ChallengeEditor/index.js +++ b/src/components/ChallengeEditor/index.js @@ -8,8 +8,6 @@ import moment from 'moment-timezone' import { pick } from 'lodash/fp' import { withRouter } from 'react-router-dom' import { toastr } from 'react-redux-toastr' -import xss from 'xss' - import { VALIDATION_VALUE_TYPE, PRIZE_SETS_TYPE, @@ -1704,10 +1702,7 @@ class ChallengeEditor extends Component {
- Project: - + Project: {projectDetail ? projectDetail.name : ''}
diff --git a/src/components/ChallengesComponent/index.js b/src/components/ChallengesComponent/index.js index 6fa3adc0..a69bdd9a 100644 --- a/src/components/ChallengesComponent/index.js +++ b/src/components/ChallengesComponent/index.js @@ -10,7 +10,6 @@ import { CONNECT_APP_URL, PROJECT_ROLES } from '../../config/constants' import { PrimaryButton } from '../Buttons' import ChallengeList from './ChallengeList' import styles from './ChallengesComponent.module.scss' -import xss from 'xss' import { checkReadOnlyRoles } from '../../util/tc' const ChallengesComponent = ({ @@ -61,12 +60,9 @@ const ChallengesComponent = ({ {!dashboard &&
-
+
+ {activeProject ? activeProject.name : ''} +
{activeProject && activeProject.id && ( ( diff --git a/src/components/ProjectCard/index.js b/src/components/ProjectCard/index.js index c133a5fa..39016cb2 100644 --- a/src/components/ProjectCard/index.js +++ b/src/components/ProjectCard/index.js @@ -2,7 +2,6 @@ import React from 'react' import PT from 'prop-types' import { Link } from 'react-router-dom' import cn from 'classnames' -import xss from 'xss' import styles from './ProjectCard.module.scss' @@ -14,7 +13,7 @@ const ProjectCard = ({ projectName, projectId, selected, setActiveProject }) => className={cn(styles.projectName, { [styles.selected]: selected })} onClick={() => setActiveProject(parseInt(projectId))} > -
+
{projectName}
) From 9db44beada425b9de741b981084371fdc0543482 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Thu, 12 Dec 2024 19:22:54 +0100 Subject: [PATCH 12/18] fix: poor validation cross site scripting --- src/routes.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes.js b/src/routes.js index f4ca4487..01716670 100644 --- a/src/routes.js +++ b/src/routes.js @@ -94,9 +94,9 @@ class Routes extends React.Component { getFreshToken().then((token) => { this.props.saveToken(token) }).catch((error) => { - console.error(error) - const redirectBackToUrl = window.location.origin + this.props.location.pathname - window.location = ACCOUNTS_APP_LOGIN_URL + '?retUrl=' + redirectBackToUrl + console.error(error.message) + const redirectBackToUrl = encodeURIComponent(window.location.origin + this.props.location.pathname) + window.location = `${ACCOUNTS_APP_LOGIN_URL}?retUrl=${redirectBackToUrl}` }) } From 04a3e2290db629d4ec81b565beff60bbf4cbfb79 Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Fri, 13 Dec 2024 05:54:10 +1100 Subject: [PATCH 13/18] Fix code scanning alert no. 19: Incomplete regular expression for hostnames Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index f822b9ba..26460c85 100644 --- a/src/index.js +++ b/src/index.js @@ -12,7 +12,7 @@ ReactDOM.render(, document.getElementById('root')) // // SAST/open-redirect handling: make sure script hostname matches what we expect -if ((new URL(UNIVERSAL_NAV_URL)).hostname.match(/uni-nav.topcoder(-dev)?.com$/i)) { +if ((new URL(UNIVERSAL_NAV_URL)).hostname.match(/uni-nav\.topcoder(-dev)?\.com$/i)) { // eslint-disable-next-line no-unused-expressions !(function (n, t, e, a, c, i, o) { // eslint-disable-next-line no-unused-expressions, no-sequences From 74515a61d0fab53d5a46f125360a85d9e3edfde0 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Thu, 12 Dec 2024 22:56:49 +0100 Subject: [PATCH 14/18] fix: deleted dockerfile --- test-automation/Dockerfile | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 test-automation/Dockerfile diff --git a/test-automation/Dockerfile b/test-automation/Dockerfile deleted file mode 100644 index 843a120a..00000000 --- a/test-automation/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -FROM node:10.17.0-stretch -RUN useradd -m -s /bin/bash appuser -RUN apt update -RUN apt install sudo -RUN sudo apt-get update; sudo apt-get install -y openjdk-8-jre openjdk-8-jre-headless openjdk-8-jdk openjdk-8-jdk-headless; -RUN curl --silent --show-error --location --fail --retry 3 --output /tmp/google-chrome-stable_current_amd64.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \ - && (sudo dpkg -i /tmp/google-chrome-stable_current_amd64.deb || sudo apt-get -fy install) \ - && rm -rf /tmp/google-chrome-stable_current_amd64.deb \ - && sudo sed -i 's|HERE/chrome"|HERE/chrome" --disable-setuid-sandbox --no-sandbox|g' \ - "/opt/google/chrome/google-chrome" \ - && google-chrome --version -RUN export CHROMEDRIVER_RELEASE=$(curl --location --fail --retry 3 http://chromedriver.storage.googleapis.com/LATEST_RELEASE) \ - && curl --silent --show-error --location --fail --retry 3 --output /tmp/chromedriver_linux64.zip "http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_RELEASE/chromedriver_linux64.zip" \ - && cd /tmp \ - && unzip chromedriver_linux64.zip \ - && rm -rf chromedriver_linux64.zip \ - && sudo mv chromedriver /usr/local/bin/chromedriver \ - && sudo chmod +x /usr/local/bin/chromedriver \ - && chromedriver --version -RUN sudo apt-get install -y libgconf-2-4 -RUN sudo apt-get install -y xvfb -RUN sudo apt-get install -y jq -ENV DISPLAY :99 -RUN printf '#!/bin/sh\nXvfb :99 -screen 0 1280x1024x24 &\nexec "$@"\n' > /tmp/entrypoint \ - && chmod +x /tmp/entrypoint \ - && sudo mv /tmp/entrypoint /docker-entrypoint.sh - -COPY . /test-automation -WORKDIR /test-automation -RUN chown -R appuser:appuser /test-automation -USER appuser -RUN npm install -RUN ./node_modules/.bin/webdriver-manager update --versions.chrome=="$(google-chrome -version)" -ENTRYPOINT ["/docker-entrypoint.sh"] -CMD ["/bin/sh"] \ No newline at end of file From 0d24df3aa937ad925542e760359fcc4d3d25fdc0 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Wed, 18 Dec 2024 11:04:01 +0100 Subject: [PATCH 15/18] fix: added https to nav url as it is breaking url constructor --- config/constants/development.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/constants/development.js b/config/constants/development.js index 07d39092..55db9b79 100644 --- a/config/constants/development.js +++ b/config/constants/development.js @@ -51,7 +51,7 @@ module.exports = { // duration to show the prompt saying user will be logged out, before actually logging out the user IDLE_TIMEOUT_GRACE_MINUTES: 5, MULTI_ROUND_CHALLENGE_TEMPLATE_ID: 'd4201ca4-8437-4d63-9957-3f7708184b07', - UNIVERSAL_NAV_URL: '//uni-nav.topcoder-dev.com/v1/tc-universal-nav.js', + UNIVERSAL_NAV_URL: 'https://uni-nav.topcoder-dev.com/v1/tc-universal-nav.js', HEADER_AUTH_URLS_HREF: `https://accounts-auth0.${DOMAIN}?utm_source=community-app-main`, HEADER_AUTH_URLS_LOCATION: `https://accounts-auth0.${DOMAIN}?retUrl=%S&utm_source=community-app-main`, SKILLS_V5_API_URL: `${API_V5}/standardized-skills/skills/autocomplete`, From d908ec805f262503f70157b96d8cf68c0ad176f8 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Wed, 18 Dec 2024 11:06:42 +0100 Subject: [PATCH 16/18] fix: added https to nav url as it is breaking url constructor --- config/constants/production.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/constants/production.js b/config/constants/production.js index 6e5e6e64..84fc03c0 100644 --- a/config/constants/production.js +++ b/config/constants/production.js @@ -48,7 +48,7 @@ module.exports = { IDLE_TIMEOUT_MINUTES: 10, IDLE_TIMEOUT_GRACE_MINUTES: 5, MULTI_ROUND_CHALLENGE_TEMPLATE_ID: 'd4201ca4-8437-4d63-9957-3f7708184b07', - UNIVERSAL_NAV_URL: '//uni-nav.topcoder.com/v1/tc-universal-nav.js', + UNIVERSAL_NAV_URL: 'https://uni-nav.topcoder.com/v1/tc-universal-nav.js', HEADER_AUTH_URLS_HREF: `https://accounts-auth0.${DOMAIN}?utm_source=community-app-main`, HEADER_AUTH_URLS_LOCATION: `https://accounts-auth0.${DOMAIN}?retUrl=%S&utm_source=community-app-main`, SKILLS_V5_API_URL: `${API_V5}/standardized-skills/skills/autocomplete`, From 0630a14d99f65561f95e2bcf1e2883789eb2e260 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 18 Dec 2024 16:22:25 +0530 Subject: [PATCH 17/18] PM-218 Fix DOS issues with fs --- config/env.js | 2 +- config/paths.js | 2 +- config/webpack.config.js | 5 +---- scripts/build.js | 2 +- scripts/start.js | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/config/env.js b/config/env.js index afe5d437..fba3ab29 100644 --- a/config/env.js +++ b/config/env.js @@ -49,7 +49,7 @@ dotenvFiles.forEach(dotenvFile => { // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. // https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421 // We also resolve them to make sure all tools using them work consistently. -const appDirectory = fs.realpathSync(process.cwd()) +const appDirectory = process.cwd() process.env.NODE_PATH = (process.env.NODE_PATH || '') .split(path.delimiter) .filter(folder => folder && !path.isAbsolute(folder)) diff --git a/config/paths.js b/config/paths.js index dbd6246b..a55133df 100644 --- a/config/paths.js +++ b/config/paths.js @@ -6,7 +6,7 @@ const url = require('url') // Make sure any symlinks in the project folder are resolved: // https://github.com/facebook/create-react-app/issues/637 -const appDirectory = fs.realpathSync(process.cwd()) +const appDirectory = process.cwd() const resolveApp = relativePath => path.resolve(appDirectory, relativePath) const envPublicUrl = process.env.PUBLIC_URL diff --git a/config/webpack.config.js b/config/webpack.config.js index d77bd35c..c5d2c025 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -27,9 +27,6 @@ const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false' // makes for a smoother build process. const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false' -// Check if TypeScript is setup -const useTypeScript = fs.existsSync(paths.appTsConfig) - // style files regexes const cssRegex = /\.css$/ const cssModuleRegex = /\.module\.css$/ @@ -257,7 +254,7 @@ module.exports = function (webpackEnv) { // for React Native Web. extensions: paths.moduleFileExtensions .map(ext => `.${ext}`) - .filter(ext => useTypeScript || !ext.includes('ts')), + .filter(ext => !ext.includes('ts')), alias: { // Support React Native Web // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ diff --git a/scripts/build.js b/scripts/build.js index eef55b65..60909f24 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -28,7 +28,7 @@ const printBuildError = require('react-dev-utils/printBuildError') const measureFileSizesBeforeBuild = FileSizeReporter.measureFileSizesBeforeBuild const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild -const useYarn = fs.existsSync(paths.yarnLockFile) +const useYarn = false // These sizes are pretty large. We'll warn for bundles exceeding them. const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024 diff --git a/scripts/start.js b/scripts/start.js index 71d668f7..47f9f854 100644 --- a/scripts/start.js +++ b/scripts/start.js @@ -32,7 +32,7 @@ const paths = require('../config/paths') const configFactory = require('../config/webpack.config') const createDevServerConfig = require('../config/webpackDevServer.config') -const useYarn = fs.existsSync(paths.yarnLockFile) +const useYarn = true const isInteractive = process.stdout.isTTY // Warn and crash if required files are missing From afe1c7cd507a26463e42ee4905520f6c55156598 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 18 Dec 2024 16:25:23 +0530 Subject: [PATCH 18/18] Typo --- scripts/start.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/start.js b/scripts/start.js index 47f9f854..57864185 100644 --- a/scripts/start.js +++ b/scripts/start.js @@ -32,7 +32,7 @@ const paths = require('../config/paths') const configFactory = require('../config/webpack.config') const createDevServerConfig = require('../config/webpackDevServer.config') -const useYarn = true +const useYarn = false const isInteractive = process.stdout.isTTY // Warn and crash if required files are missing