fix ssh key parsing

This commit is contained in:
root
2026-06-04 00:13:58 -04:00
parent e0b2239f66
commit 52c1ecffe2
4 changed files with 130 additions and 3 deletions
@@ -0,0 +1,93 @@
'use client'
import { usePathname, useRouter } from 'next/navigation'
import { useEffect, useState } from 'react'
import { apiFetch } from '@/lib/api'
import { toDashboardAppPath, toPublicDashboardPath } from '@/lib/dashboardPaths'
type GeneratedMenuItem = {
id: string
itemType: 'INTERNAL_PAGE' | 'EXTERNAL_LINK' | 'PARENT_MENU' | 'SECTION_LABEL' | 'DIVIDER'
routeOrUrl: string | null
children: GeneratedMenuItem[]
}
type EmployeeMenuResponse = {
items: GeneratedMenuItem[]
}
function flattenInternalRoutes(items: GeneratedMenuItem[]): string[] {
const routes: string[] = []
const walk = (entry: GeneratedMenuItem) => {
if (entry.itemType === 'INTERNAL_PAGE' && entry.routeOrUrl) {
routes.push(entry.routeOrUrl)
}
entry.children.forEach(walk)
}
items.forEach(walk)
return routes
}
function isAllowedRoute(currentPath: string, allowedRoutes: string[]) {
return allowedRoutes.some((route) => {
if (route === '/') return currentPath === '/'
return currentPath === route || currentPath.startsWith(`${route}/`)
})
}
export default function DashboardAccessGuard({ children }: { children: React.ReactNode }) {
const pathname = usePathname()
const router = useRouter()
const [ready, setReady] = useState(false)
useEffect(() => {
let cancelled = false
async function enforceAccess() {
try {
setReady(false)
const currentPath = toDashboardAppPath(pathname)
const menu = await apiFetch<EmployeeMenuResponse>('/auth/employee/menu')
if (cancelled) return
const allowedRoutes = flattenInternalRoutes(menu.items)
const fallbackRoute = allowedRoutes[0] ?? '/'
if (!isAllowedRoute(currentPath, allowedRoutes)) {
router.replace(toPublicDashboardPath(fallbackRoute))
return
}
setReady(true)
} catch (error: any) {
if (cancelled) return
if (error?.statusCode === 401 || error?.statusCode === 403 || error?.statusCode === 402) {
router.replace(toPublicDashboardPath('/'))
return
}
// Do not deadlock the dashboard on transient network failures.
setReady(true)
}
}
enforceAccess()
return () => {
cancelled = true
}
}, [pathname, router])
if (!ready) {
return (
<div className="flex min-h-[40vh] items-center justify-center">
<div className="h-6 w-6 animate-spin rounded-full border-2 border-orange-500 border-t-transparent" aria-label="Checking access" />
</div>
)
}
return <>{children}</>
}