Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev to hotfix #2298

Merged
merged 19 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cipp",
"version": "5.4.0",
"version": "5.4.1",
"description": "The CyberDrain Improved Partner Portal is a portal to help manage administration for Microsoft Partners.",
"homepage": "https://cipp.app/",
"bugs": {
Expand Down
2 changes: 1 addition & 1 deletion public/version_latest.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.4.0
5.4.1
40 changes: 8 additions & 32 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,26 @@ import React, { Suspense } from 'react'
import { BrowserRouter, Route, Routes, Navigate } from 'react-router-dom'
import { PrivateRoute, FullScreenLoading, ErrorBoundary } from 'src/components/utilities'
import 'src/scss/style.scss'
import routes from 'src/routes'
import { Helmet } from 'react-helmet-async'
import adminRoutes from './adminRoutes'
import Skeleton from 'react-loading-skeleton'
import TimeAgo from 'javascript-time-ago'
import en from 'javascript-time-ago/locale/en.json'
TimeAgo.addDefaultLocale(en)
import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'
import routes from 'src/routes'
import { useAuthCheck } from './components/utilities/CippauthCheck'

library.add(fas)

// Containers
const dynamicImport = (path) => React.lazy(() => import(`./${path}`))
const DefaultLayout = React.lazy(() => import('./layout/DefaultLayout'))

// Pages
const Page401 = React.lazy(() => import('./views/pages/page401/Page401'))
const Page403 = React.lazy(() => import('./views/pages/page403/Page403'))
const Page404 = React.lazy(() => import('./views/pages/page404/Page404'))
const Page500 = React.lazy(() => import('./views/pages/page500/Page500'))
const PageLogOut = React.lazy(() => import('src/views/pages/LogoutRedirect/PageLogOut'))
const Login = React.lazy(() => import('./views/pages/login/Login'))
const Logout = React.lazy(() => import('./views/pages/login/Logout'))

const App = () => {
return (
<BrowserRouter>
Expand All @@ -50,43 +46,23 @@ const App = () => {
}
>
{routes.map((route, idx) => {
const Component = dynamicImport(route.component)
const allowedRoles = route.allowedRoles
return (
route.component && (
<Route
key={`route-${idx}`}
path={route.path}
exact={route.exact}
name={route.name}
element={
<Suspense fallback={<Skeleton />}>
<Helmet>
<title>CIPP - {route.name}</title>
</Helmet>
<ErrorBoundary key={route.name}>
<route.component />
</ErrorBoundary>
</Suspense>
}
/>
)
)
})}
{adminRoutes.map((route, idx) => {
return (
route.component && (
Component && (
<Route
key={`route-${idx}`}
path={route.path}
exact={route.exact}
name={route.name}
element={
<PrivateRoute routeType="admin">
<PrivateRoute allowedRoles={allowedRoles}>
<Suspense fallback={<Skeleton />}>
<Helmet>
<title>CIPP - {route.name}</title>
</Helmet>
<ErrorBoundary key={route.name}>
<route.component />
<Component />
</ErrorBoundary>
</Suspense>
</PrivateRoute>
Expand Down
76 changes: 0 additions & 76 deletions src/adminRoutes.js

This file was deleted.

3 changes: 2 additions & 1 deletion src/components/forms/RFFComponents.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,11 @@ export const RFFCFormInput = ({
spellCheck = true,
autoFocus = false,
hiddenValue,
defaultValue,
onChange,
}) => {
return (
<Field initialValue={hiddenValue} name={name} validate={validate}>
<Field defaultValue={defaultValue} initialValue={hiddenValue} name={name} validate={validate}>
{({ input, meta }) => {
const handleChange = onChange
? (e) => {
Expand Down
8 changes: 7 additions & 1 deletion src/components/layout/AppSidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import { AppSidebarNav } from 'src/components/layout'
import SimpleBar from 'simplebar-react'
import 'simplebar/dist/simplebar.min.css'
import navigation from 'src/_nav'
import { useAuthCheck } from '../utilities/CippauthCheck'
import routes from 'src/routes'
import { useRouteNavCompare } from 'src/hooks/useRouteNavCompare'
import { useNavFavouriteCheck } from 'src/hooks/useNavFavouriteCheck'

const AppSidebar = () => {
const i =
Expand All @@ -22,6 +26,8 @@ const AppSidebar = () => {
if (!i.includes('JGySCBt1QXmNc')) {
throw ''
}
const newNav = useRouteNavCompare(navigation)
const navwithFavourites = useNavFavouriteCheck(newNav)
return (
<CSidebar
onVisibleChange={(visible) => {
Expand All @@ -41,7 +47,7 @@ const AppSidebar = () => {
/>
<CSidebarNav>
<SimpleBar>
<AppSidebarNav items={navigation} />
<AppSidebarNav items={navwithFavourites} />
</SimpleBar>
</CSidebarNav>
</CSidebar>
Expand Down
7 changes: 6 additions & 1 deletion src/components/tables/CellTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ export default function cellTable(
columnProp = column
}

if (!Array.isArray(columnProp) && typeof columnProp === 'object') {
if (
!Array.isArray(columnProp) &&
typeof columnProp === 'object' &&
columnProp !== undefined &&
columnProp !== null
) {
columnProp = Object.keys(columnProp).map((key) => {
return {
[key]: columnProp[key],
Expand Down
27 changes: 27 additions & 0 deletions src/components/utilities/CippauthCheck.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useLoadClientPrincipalQuery } from 'src/store/api/auth'
import { useDispatch } from 'react-redux'
import { updateAccessToken } from 'src/store/features/auth'
import { Navigate } from 'react-router-dom'

export const useAuthCheck = (allowedRoles) => {
const dispatch = useDispatch()
const { data: profile, isFetching } = useLoadClientPrincipalQuery()
if (isFetching) {
return { isLoading: true, component: null }
}
dispatch(updateAccessToken(profile))
let roles = profile?.clientPrincipal?.userRoles || []

if (!profile?.clientPrincipal) {
return {
component: (
<Navigate to={`/login?redirect_uri=${encodeURIComponent(window.location.href)}`} />
),
result: false,
}
}
if (allowedRoles && !allowedRoles.some((role) => roles.includes(role))) {
return { component: <Navigate to="/403" />, result: true }
}
return { component: null, result: false }
}
39 changes: 9 additions & 30 deletions src/components/utilities/PrivateRoute.jsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,20 @@
import React from 'react'
import { Navigate } from 'react-router-dom'
import { useLoadClientPrincipalQuery } from 'src/store/api/auth'
import { FullScreenLoading } from 'src/components/utilities'
import { useDispatch } from 'react-redux'
import { updateAccessToken } from 'src/store/features/auth'
import PropTypes from 'prop-types'
import { useAuthCheck } from './CippauthCheck'

export const PrivateRoute = ({ children, routeType }) => {
const dispatch = useDispatch()
const { data: profile, error, isFetching } = useLoadClientPrincipalQuery()
//console.log()
if (isFetching) {
export const PrivateRoute = ({ children, allowedRoles }) => {
const { isLoading, component: authComponent } = useAuthCheck(allowedRoles)
if (isLoading) {
return <FullScreenLoading />
}

dispatch(updateAccessToken(profile))
let roles = null
if (null !== profile?.clientPrincipal) {
roles = profile?.clientPrincipal.userRoles
} else if (null === profile?.clientPrincipal) {
return <Navigate to={`/login?redirect_uri=${window.location.href}`} />
}
if (null === roles) {
return <Navigate to={`/login?redirect_uri=${window.location.href}`} />
} else {
const isAuthenticated =
roles.includes('admin') || roles.includes('editor') || (roles.includes('readonly') && !error)
const isAdmin = roles.includes('admin')
if (routeType === 'admin') {
return !isAdmin ? <Navigate to="/403" /> : children
} else {
return !isAuthenticated ? <Navigate to="/403" /> : children
}
if (authComponent) {
return authComponent
}
return children
}

PrivateRoute.propTypes = {
children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
routeType: PropTypes.string,
children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]).isRequired,
allowedRoles: PropTypes.arrayOf(PropTypes.string),
}
8 changes: 7 additions & 1 deletion src/components/utilities/TenantSelector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,20 @@ const TenantSelector = ({ action, showAllTenantSelector = true, NavSelector = fa
const Paramcount = Array.from(searchParams).length
if (Paramcount <= 1) {
const customerId = searchParams.get('customerId')
const tableFilter = searchParams.get('tableFilter')
var newSearchParams = {}
if (tableFilter) {
newSearchParams.tableFilter = tableFilter
}
if (customerId && isSuccess) {
const currentTenant = tenants.filter((tenant) => tenant.customerId === customerId)
if (currentTenant.length > 0) {
dispatch(setCurrentTenant({ tenant: currentTenant[0] }))
}
}
if (!customerId && Object.keys(currentTenant).length > 0) {
updateSearchParams({ customerId: currentTenant?.customerId })
newSearchParams.customerId = currentTenant?.customerId
updateSearchParams(newSearchParams)
}
}
}, [dispatch, isSuccess, searchParams, currentTenant, tenants, updateSearchParams])
Expand Down
Loading
Loading