From 6d230de2368bb936b15baa22da73ff13b2131541 Mon Sep 17 00:00:00 2001 From: David Lyon Date: Tue, 4 Feb 2025 10:56:32 -0800 Subject: [PATCH 1/4] stub out CDM navigation and add role-controlled NavItems and Routes --- src/app/Routes.tsx | 32 ++++++++++++++++- src/features/cdm/CDMRedirectPage.tsx | 8 +++++ src/features/layout/LeftNavBar.tsx | 51 ++++++++++++---------------- 3 files changed, 60 insertions(+), 31 deletions(-) create mode 100644 src/features/cdm/CDMRedirectPage.tsx diff --git a/src/app/Routes.tsx b/src/app/Routes.tsx index d1ee5dbb..5a090800 100644 --- a/src/app/Routes.tsx +++ b/src/app/Routes.tsx @@ -37,6 +37,9 @@ import { AccountInfo } from '../features/account/AccountInfo'; import { LinkedProviders } from '../features/account/LinkedProviders'; import { LogInSessions } from '../features/account/LogInSessions'; import { UseAgreements } from '../features/account/UseAgreements'; +import { CDMRedirectPage } from '../features/cdm/CDMRedirectPage'; +import { skipToken } from '@reduxjs/toolkit/dist/query'; +import { getMe } from '../common/api/authService'; export const LOGIN_ROUTE = '/login'; export const SIGNUP_ROUTE = '/signup'; @@ -131,6 +134,17 @@ const Routes: FC = () => { } />} /> + {/* CDM */} + } + /> + } + /> + {/* IFrame Fallback Routes */} { ); }; -export const Authed: FC<{ element: ReactElement }> = ({ element }) => { +export const Authed: FC<{ element: ReactElement; roles?: string[] }> = ({ + element, + roles, +}) => { const token = useAppSelector((state) => state.auth.token); const location = useLocation(); + + const { data: me } = getMe.useQuery(token ? { token } : skipToken); + const myRoles = new Set([ + ...(me?.roles.map((r) => r.id) || []), + ...(me?.customroles || []), + ]); + const specifiedRolesPresent = + roles?.length && roles.every((role) => myRoles.has(role)); + if (!token) { return ( = ({ element }) => { ); } + if (roles && !specifiedRolesPresent) { + return ; + } + return <>{element}; }; diff --git a/src/features/cdm/CDMRedirectPage.tsx b/src/features/cdm/CDMRedirectPage.tsx new file mode 100644 index 00000000..19f88fe6 --- /dev/null +++ b/src/features/cdm/CDMRedirectPage.tsx @@ -0,0 +1,8 @@ +export const CDMRedirectPage = () => { + return ( + <> + This page does not yet exist. Visit{' '} + 127.0.0.1:4043 + + ); +}; diff --git a/src/features/layout/LeftNavBar.tsx b/src/features/layout/LeftNavBar.tsx index 657d1f43..c816d9b5 100644 --- a/src/features/layout/LeftNavBar.tsx +++ b/src/features/layout/LeftNavBar.tsx @@ -14,16 +14,18 @@ import { faQuestionCircle, faServer, faNoteSticky, + faDatabase, } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon as FAIcon } from '@fortawesome/react-fontawesome'; import { FC, useState } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { getFeedsUnseenCount } from '../../common/api/feedsService'; import { useAppSelector } from '../../common/hooks'; -import { authMe, authToken } from '../auth/authSlice'; -import { useAuthMe } from '../auth/hooks'; +import { authToken } from '../auth/authSlice'; import classes from './LeftNavBar.module.scss'; import { Button, Menu, MenuItem } from '@mui/material'; +import { getMe } from '../../common/api/authService'; +import { skipToken } from '@reduxjs/toolkit/dist/query'; const LeftNavBar: FC = () => { const token = useAppSelector(authToken); @@ -64,7 +66,14 @@ const LeftNavBar: FC = () => { badge={'beta'} badgeColor={'primary'} /> - +
+ { + CDMRedirectFormSubmit.current = submit; + }} + /> ); }; const NavItem: FC<{ path: string; + onClick?: () => void; desc: string; icon: IconDefinition; badge?: number | string; badgeColor?: string; requiredRole?: string; -}> = ({ path, desc, icon, badge, badgeColor, requiredRole }) => { +}> = ({ path, onClick, desc, icon, badge, badgeColor, requiredRole }) => { const location = useLocation(); const token = useAppSelector(authToken); const { data: me } = getMe.useQuery(token ? { token } : skipToken); @@ -175,7 +186,7 @@ const NavItem: FC<{ if (requiredRole && !myRoles.has(requiredRole)) return <>; return (
  • - + {desc} {badge ? ( From 872463f1263cb918dd241da2c4d8c5e44f6e454f Mon Sep 17 00:00:00 2001 From: David Lyon Date: Wed, 5 Feb 2025 14:58:43 -0800 Subject: [PATCH 3/4] Update CDM login redirect URL --- src/features/cdm/CDMRedirectForm.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/features/cdm/CDMRedirectForm.tsx b/src/features/cdm/CDMRedirectForm.tsx index 00414daa..b7f4c0af 100644 --- a/src/features/cdm/CDMRedirectForm.tsx +++ b/src/features/cdm/CDMRedirectForm.tsx @@ -5,9 +5,8 @@ export const CDMRedirectForm = ({ }) => { // All this page does is send a POST login request to the CDM // User will need a cookie for this to succeed. - //TODO: UDPATE THIS URL - const CDMOrigin = 'http://127.0.0.1:4043'; - const loginUrl = `${CDMOrigin}/hub/login`; + const KBASE_DOMAIN = process.env.REACT_APP_KBASE_DOMAIN || 'ci.kbase.us'; + const loginUrl = `https://cdmhub.${KBASE_DOMAIN}/hub/login`; return (
    Date: Wed, 5 Feb 2025 15:50:30 -0800 Subject: [PATCH 4/4] switch redirect strategies, dont send POST due to jupyter xrsf cookie constraints --- src/app/Routes.tsx | 6 ++++++ src/features/cdm/CDMRedirect.tsx | 23 +++++++++++++++++++++++ src/features/cdm/CDMRedirectForm.tsx | 23 ----------------------- src/features/layout/LeftNavBar.tsx | 14 ++------------ 4 files changed, 31 insertions(+), 35 deletions(-) create mode 100644 src/features/cdm/CDMRedirect.tsx delete mode 100644 src/features/cdm/CDMRedirectForm.tsx diff --git a/src/app/Routes.tsx b/src/app/Routes.tsx index a5a8269f..6a39c63d 100644 --- a/src/app/Routes.tsx +++ b/src/app/Routes.tsx @@ -39,6 +39,7 @@ import { LogInSessions } from '../features/account/LogInSessions'; import { UseAgreements } from '../features/account/UseAgreements'; import { skipToken } from '@reduxjs/toolkit/dist/query'; import { getMe } from '../common/api/authService'; +import { CDMRedirect } from '../features/cdm/CDMRedirect'; export const LOGIN_ROUTE = '/login'; export const SIGNUP_ROUTE = '/signup'; @@ -133,6 +134,11 @@ const Routes: FC = () => { } />} /> + {/* CDM */} + + } />} /> + + {/* IFrame Fallback Routes */} { + useEffect(() => { + window.location.href = `https://cdmhub.${process.env.REACT_APP_KBASE_DOMAIN}/hub`; + }); + return ( + + + +
    Redirecting to CDM
    +
    +
    + ); +}; diff --git a/src/features/cdm/CDMRedirectForm.tsx b/src/features/cdm/CDMRedirectForm.tsx deleted file mode 100644 index b7f4c0af..00000000 --- a/src/features/cdm/CDMRedirectForm.tsx +++ /dev/null @@ -1,23 +0,0 @@ -export const CDMRedirectForm = ({ - ready, -}: { - ready: (submit: () => void) => void; -}) => { - // All this page does is send a POST login request to the CDM - // User will need a cookie for this to succeed. - const KBASE_DOMAIN = process.env.REACT_APP_KBASE_DOMAIN || 'ci.kbase.us'; - const loginUrl = `https://cdmhub.${KBASE_DOMAIN}/hub/login`; - return ( - { - if (formElement) - ready(() => { - formElement?.submit(); - }); - }} - > - ); -}; diff --git a/src/features/layout/LeftNavBar.tsx b/src/features/layout/LeftNavBar.tsx index 6685ad9a..32817209 100644 --- a/src/features/layout/LeftNavBar.tsx +++ b/src/features/layout/LeftNavBar.tsx @@ -17,7 +17,7 @@ import { faDatabase, } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon as FAIcon } from '@fortawesome/react-fontawesome'; -import { FC, useRef, useState } from 'react'; +import { FC, useState } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { getFeedsUnseenCount } from '../../common/api/feedsService'; import { useAppSelector } from '../../common/hooks'; @@ -26,7 +26,6 @@ import classes from './LeftNavBar.module.scss'; import { Button, Menu, MenuItem } from '@mui/material'; import { getMe } from '../../common/api/authService'; import { skipToken } from '@reduxjs/toolkit/dist/query'; -import { CDMRedirectForm } from '../cdm/CDMRedirectForm'; const LeftNavBar: FC = () => { const token = useAppSelector(authToken); @@ -44,7 +43,6 @@ const LeftNavBar: FC = () => { const handleCloseMoreMenu = () => { setAnchorEl(null); }; - const CDMRedirectFormSubmit = useRef<() => void>(); return ( ); };