From ff855cf79c762fcf9cca7aa8d656af682c10f7b2 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 26 Mar 2025 16:04:10 +0530 Subject: [PATCH 01/33] Allow hyphen in url - asset library --- src/util/validation.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/util/validation.js b/src/util/validation.js index 7f7e7c70..d20132e2 100644 --- a/src/util/validation.js +++ b/src/util/validation.js @@ -58,8 +58,7 @@ export const taaSProjectFormValidationSchema = Yup.object({ /** * regex for url validation */ -const urlRegex = /((https?):\/\/)?(www.)?[a-z0-9]+(\.[a-z]{2,}){1,3}(#?\/?(?:[a-zA-Z0-9#]+))*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ - +const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?([\w-._~:/?#[\]@!$&'()*+,;=]+)*)?\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ /** * validation schema for add link form in assets library */ From a70e1a503e0c5aeb38f3342ae7f687fe460bc70a Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 26 Mar 2025 16:18:00 +0530 Subject: [PATCH 02/33] git copilot suggestion --- src/util/validation.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/util/validation.js b/src/util/validation.js index d20132e2..c1de86e7 100644 --- a/src/util/validation.js +++ b/src/util/validation.js @@ -58,7 +58,8 @@ export const taaSProjectFormValidationSchema = Yup.object({ /** * regex for url validation */ -const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?([\w-._~:/?#[\]@!$&'()*+,;=]+)*)?\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ +const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?([\w\-._~:/?#[\]@!$&'()*+,;=]+)*)?\/?(\?[a-zA-Z0-9\-_=]+(&[a-zA-Z0-9\-_=]+)*)?$/ + /** * validation schema for add link form in assets library */ From 4d24155cd453c40abd37988c26478655b63327ef Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 26 Mar 2025 16:35:21 +0530 Subject: [PATCH 03/33] Redo the fix with minimal change --- src/util/validation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/validation.js b/src/util/validation.js index c1de86e7..4a1f2121 100644 --- a/src/util/validation.js +++ b/src/util/validation.js @@ -58,7 +58,7 @@ export const taaSProjectFormValidationSchema = Yup.object({ /** * regex for url validation */ -const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?([\w\-._~:/?#[\]@!$&'()*+,;=]+)*)?\/?(\?[a-zA-Z0-9\-_=]+(&[a-zA-Z0-9\-_=]+)*)?$/ +const urlRegex = /((https?):\/\/)?(www.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?(?:[\w-#]+))*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ /** * validation schema for add link form in assets library From 6a43f6393079509c81e2edbaf24c8ad7e28d43c5 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 26 Mar 2025 16:42:02 +0530 Subject: [PATCH 04/33] Codeql test --- src/util/validation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/validation.js b/src/util/validation.js index 4a1f2121..9d6cb6ac 100644 --- a/src/util/validation.js +++ b/src/util/validation.js @@ -58,7 +58,7 @@ export const taaSProjectFormValidationSchema = Yup.object({ /** * regex for url validation */ -const urlRegex = /((https?):\/\/)?(www.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?(?:[\w-#]+))*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ +const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?(?:[a-zA-Z0-9#-]+))*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ /** * validation schema for add link form in assets library From 619b5c08fbbcafaa13dcd7c07aab2f5d0f6f929c Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 26 Mar 2025 17:38:35 +0530 Subject: [PATCH 05/33] re-iterate with codeql --- src/util/validation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/validation.js b/src/util/validation.js index 9d6cb6ac..9452b690 100644 --- a/src/util/validation.js +++ b/src/util/validation.js @@ -58,7 +58,7 @@ export const taaSProjectFormValidationSchema = Yup.object({ /** * regex for url validation */ -const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?(?:[a-zA-Z0-9#-]+))*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ +const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?(?:[\w-]+))*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ /** * validation schema for add link form in assets library From 1dee45f7f6e02089819f5169efaba4ac47b3d932 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 26 Mar 2025 17:58:20 +0530 Subject: [PATCH 06/33] Retest performance --- src/util/validation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/validation.js b/src/util/validation.js index 9452b690..4bb2c99d 100644 --- a/src/util/validation.js +++ b/src/util/validation.js @@ -58,7 +58,7 @@ export const taaSProjectFormValidationSchema = Yup.object({ /** * regex for url validation */ -const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?(?:[\w-]+))*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ +const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#-]{1,100})*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ /** * validation schema for add link form in assets library From a0fe205c45a2514f7e1b08432dbe232a4a41cb13 Mon Sep 17 00:00:00 2001 From: Himani Raghav <60837787+himaniraghav3@users.noreply.github.com> Date: Wed, 26 Mar 2025 18:40:12 +0530 Subject: [PATCH 07/33] Potential fix for code scanning alert no. 27: Inefficient regular expression Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- src/util/validation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/validation.js b/src/util/validation.js index 4bb2c99d..186d45cc 100644 --- a/src/util/validation.js +++ b/src/util/validation.js @@ -58,7 +58,7 @@ export const taaSProjectFormValidationSchema = Yup.object({ /** * regex for url validation */ -const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#-]{1,100})*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ +const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?[\w-]{1,100})*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ /** * validation schema for add link form in assets library From 374be0c10b37aec8f94e185001231bc09cc48cc3 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 26 Mar 2025 19:35:34 +0530 Subject: [PATCH 08/33] revert codeql suggestion --- src/util/validation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/validation.js b/src/util/validation.js index 186d45cc..9d6cb6ac 100644 --- a/src/util/validation.js +++ b/src/util/validation.js @@ -58,7 +58,7 @@ export const taaSProjectFormValidationSchema = Yup.object({ /** * regex for url validation */ -const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?[\w-]{1,100})*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ +const urlRegex = /((https?):\/\/)?(www\.)?[\w-]+(\.[a-z]{2,}){1,3}(#?\/?(?:[a-zA-Z0-9#-]+))*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/ /** * validation schema for add link form in assets library From 1b719fb0776d8303ca94fe7f0d83eee1b36eb62d Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Thu, 27 Mar 2025 23:07:09 +0100 Subject: [PATCH 09/33] feat: added show only my projects for project managers --- src/actions/projects.js | 4 +- src/config/constants.js | 4 ++ src/containers/Projects/index.js | 39 ++++++++-- src/containers/Projects/styles.module.scss | 82 ++++++++++++++++++++++ src/util/tc.js | 8 ++- 5 files changed, 129 insertions(+), 8 deletions(-) diff --git a/src/actions/projects.js b/src/actions/projects.js index 2d88e519..56f803ee 100644 --- a/src/actions/projects.js +++ b/src/actions/projects.js @@ -32,7 +32,7 @@ import { fetchMemberProjects, updateProjectApi } from '../services/projects' -import { checkAdmin } from '../util/tc' +import { checkAdmin, checkManager } from '../util/tc' function _loadProjects (projectNameOrIdFilter = '', paramFilters = {}) { return (dispatch, getState) => { @@ -54,7 +54,7 @@ function _loadProjects (projectNameOrIdFilter = '', paramFilters = {}) { } } - if (!checkAdmin(getState().auth.token)) { + if (!checkAdmin(getState().auth.token) && !checkManager(getState().auth.token)) { filters['memberOnly'] = true } diff --git a/src/config/constants.js b/src/config/constants.js index 6aa99441..1310acb4 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -308,6 +308,10 @@ export const COPILOT_ROLES = [ 'copilot' ] +export const MANAGER_ROLES = [ + 'project manager' +] + export const downloadAttachmentURL = (challengeId, attachmentId, token) => `${CHALLENGE_API_URL}/${challengeId}/attachments/${attachmentId}/download?token=${token}` diff --git a/src/containers/Projects/index.js b/src/containers/Projects/index.js index 733c044c..b427c8a8 100644 --- a/src/containers/Projects/index.js +++ b/src/containers/Projects/index.js @@ -5,7 +5,7 @@ import { withRouter, Link } from 'react-router-dom' import { connect } from 'react-redux' import PropTypes from 'prop-types' import Loader from '../../components/Loader' -import { checkAdminOrCopilot } from '../../util/tc' +import { checkAdminOrCopilot, checkManager } from '../../util/tc' import { PrimaryButton } from '../../components/Buttons' import Select from '../../components/Select' import ProjectCard from '../../components/ProjectCard' @@ -18,11 +18,21 @@ import styles from './styles.module.scss' const Projects = ({ projects, auth, isLoading, projectsCount, loadProjects, loadMoreProjects, unloadProjects }) => { const [search, setSearch] = useState() const [projectStatus, setProjectStatus] = useState('') + const [showOnlyMyProjects, setOnlyMyProjects] = useState(true) const selectedStatus = useMemo(() => PROJECT_STATUSES.find(s => s.value === projectStatus)) + const isProjectManager = checkManager(auth.token) useEffect(() => { - loadProjects(search, projectStatus ? { status: projectStatus } : {}) - }, [search, projectStatus]) + const params = {} + if (projectStatus) { + params.status = projectStatus + } + console.log(isProjectManager, showOnlyMyProjects) + if (isProjectManager) { + params.memberOnly = showOnlyMyProjects + } + loadProjects(search, params) + }, [search, projectStatus, showOnlyMyProjects, isProjectManager]) // unload projects on dismount useEffect(() => () => unloadProjects, []) @@ -46,7 +56,7 @@ const Projects = ({ projects, auth, isLoading, projectsCount, loadProjects, load )}
-
+
@@ -61,7 +71,7 @@ const Projects = ({ projects, auth, isLoading, projectsCount, loadProjects, load />
-
+
@@ -76,6 +86,25 @@ const Projects = ({ projects, auth, isLoading, projectsCount, loadProjects, load />
+
+ { + checkManager(auth.token) && ( +
+ { setOnlyMyProjects(!showOnlyMyProjects) }} + /> + +
+ ) + } +
{projects.length > 0 ? ( <> diff --git a/src/containers/Projects/styles.module.scss b/src/containers/Projects/styles.module.scss index d80341cc..ef18461d 100644 --- a/src/containers/Projects/styles.module.scss +++ b/src/containers/Projects/styles.module.scss @@ -43,6 +43,7 @@ display: flex; gap: 10px; margin-bottom: 20px; + align-items: end; .searchInput { width: 100%; height: 40px; @@ -51,4 +52,85 @@ border: 1px solid $light-gray; background-color: $lighter-gray; } + + .tcCheckbox { + @include tc-checkbox; + + .tc-checkbox-label { + @include roboto-light(); + + line-height: 17px; + font-weight: 300; + margin-left: 21px; + user-select: none; + cursor: pointer; + width: 195px; + font-size: 14px; + color: #3d3d3d; + } + + height: 18px; + width: 210px; + margin: 0; + padding: 0; + vertical-align: bottom; + position: relative; + display: inline-block; + margin-bottom: 4px; + margin-left: 8px; + + input[type=checkbox] { + display: none; + } + + label { + @include roboto-light(); + + line-height: 17px; + font-weight: 300; + cursor: pointer; + position: absolute; + display: inline-block; + width: 18px; + height: 18px; + top: 0; + left: 0; + border: none; + box-shadow: none; + background: $tc-gray-30; + transition: all 0.15s ease-in-out; + + &::after { + opacity: 0; + content: ''; + position: absolute; + width: 9px; + height: 5px; + background: transparent; + top: 5px; + left: 5px; + border-top: none; + border-right: none; + transform: rotate(-45deg); + transition: all 0.15s ease-in-out; + } + + &:hover::after { + opacity: 0.3; + } + + div { + margin-left: 24px; + width: 300px; + } + } + + input[type=checkbox]:checked ~ label { + background: $tc-blue-20; + } + + input[type=checkbox]:checked + label::after { + border-color: $white; + } + } } \ No newline at end of file diff --git a/src/util/tc.js b/src/util/tc.js index 576e9df4..d5917e3b 100644 --- a/src/util/tc.js +++ b/src/util/tc.js @@ -10,7 +10,8 @@ import { SUBMITTER_ROLE_UUID, READ_ONLY_ROLES, ALLOWED_DOWNLOAD_SUBMISSIONS_ROLES, - ALLOWED_EDIT_RESOURCE_ROLES + ALLOWED_EDIT_RESOURCE_ROLES, + MANAGER_ROLES } from '../config/constants' import _ from 'lodash' import { decodeToken } from 'tc-auth-lib' @@ -200,6 +201,11 @@ export const checkAdmin = (token) => { return roles.some(val => ADMIN_ROLES.indexOf(val.toLowerCase()) > -1) } +export const checkManager = (token) => { + const tokenData = decodeToken(token) + const roles = _.get(tokenData, 'roles') + return roles.some(val => MANAGER_ROLES.indexOf(val.toLowerCase()) > -1) +} /** * Checks if token has any of the copilot roles * @param token From 441e6d71cc2b0a7cab4a9c018249a682f47f68ba Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Thu, 27 Mar 2025 23:08:55 +0100 Subject: [PATCH 10/33] fix: removed console log --- src/containers/Projects/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/containers/Projects/index.js b/src/containers/Projects/index.js index b427c8a8..b287a020 100644 --- a/src/containers/Projects/index.js +++ b/src/containers/Projects/index.js @@ -27,7 +27,7 @@ const Projects = ({ projects, auth, isLoading, projectsCount, loadProjects, load if (projectStatus) { params.status = projectStatus } - console.log(isProjectManager, showOnlyMyProjects) + if (isProjectManager) { params.memberOnly = showOnlyMyProjects } @@ -95,7 +95,7 @@ const Projects = ({ projects, auth, isLoading, projectsCount, loadProjects, load type='checkbox' id='isOpenAdvanceSettings' checked={showOnlyMyProjects} - onChange={() => { setOnlyMyProjects(!showOnlyMyProjects) }} + onChange={() => setOnlyMyProjects(!showOnlyMyProjects)} />