diff --git a/apps/edr-freight-web/backoffice/package.json b/apps/edr-freight-web/backoffice/package.json index d680625ac..17750ddac 100644 --- a/apps/edr-freight-web/backoffice/package.json +++ b/apps/edr-freight-web/backoffice/package.json @@ -9,10 +9,7 @@ "preview": "vite preview --port 5183", "lint": "eslint src", "test": "vitest run", - "type-check": "tsc --noEmit", - "build:user-management": "cd user-management-config && npm run build", - "backoffice": "npm run build:user-management && nx serve @fhc-platform/backoffice", - "backoffice:no-build": "nx serve @fhc-platform/backoffice" + "type-check": "tsc --noEmit" }, "dependencies": { "@edr/types": "workspace:*", @@ -22,7 +19,7 @@ "@mantine/hooks": "^9.3.0", "@tabler/icons-react": "^3.44.0", "@tanstack/react-query": "^5.100.11", - "@tria-plc/iamui-common": "1.1.2", + "@tria-plc/iamui": "0.0.3", "axios": "^1.7.7", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/apps/edr-freight-web/backoffice/src/App.tsx b/apps/edr-freight-web/backoffice/src/App.tsx index e8879ba0e..46c8e73f3 100644 --- a/apps/edr-freight-web/backoffice/src/App.tsx +++ b/apps/edr-freight-web/backoffice/src/App.tsx @@ -213,41 +213,13 @@ const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[] => [ }, ], }, - { - title: "Administration", - items: [ - { - label: "User management", - href: "/dashboard/user-management", - icon: , - permission: FREIGHT_PERMS.admin, - children: [ - { - label: "Users", - href: "/dashboard/user-management/users", - }, - { - label: "Employees", - href: "/dashboard/user-management/employees", - }, - { - label: "Position Types", - href: "/dashboard/user-management/position-types", - }, - { - label: "Permissions", - href: "/dashboard/user-management/permissions", - }, - { - label: "Roles", - href: "/dashboard/user-management/roles", - }, - ], - }, - { - label: "File settings", - href: "/dashboard/file-settings", - icon: , + { + title: "Administration", + items: [ + { + label: "File settings", + href: "/dashboard/file-settings", + icon: , permission: FREIGHT_PERMS.admin, }, { @@ -340,224 +312,216 @@ const App = () => { return ; } - if (!user) { - return ( - - } /> - } /> - } /> - - ); - } + if (!user) { + return ( + + } /> + } /> + } /> + + ); + } + + return ( + + } /> + } /> + } /> + }> + } /> + } /> + + } /> + + + + } + /> + } /> + } /> + } + /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> - return ( - - } /> - } /> - }> - } /> - } /> - - } /> - - - - } - /> - } /> - } /> - } - /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - {/* iframe-based user management module */} - } /> - - {/* Legacy embedded user management routes */} - } /> - } /> - } /> - {/* } /> */} - } /> - } /> - - - - - } - /> - - - - } - /> - - } - /> - - - - } - /> - } /> - } /> - } /> - - } - /> - } /> - - } - /> - } /> - - } /> - } /> - - } - /> - } - /> - - - } /> - - ); -}; + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + {/* Legacy embedded user management routes */} + } /> + } /> + } /> + {/* } /> */} + } /> + } /> + + + + + } + /> + + + + } + /> + + } + /> + + + + } + /> + } /> + } /> + } /> + + } + /> + } /> + + } + /> + } /> + + } /> + } /> + + } /> + } /> + + + } /> + + ); +}; export default App; diff --git a/apps/edr-freight-web/backoffice/src/pages/dashboard/user-management/UserManagementHostPage.tsx b/apps/edr-freight-web/backoffice/src/pages/dashboard/user-management/UserManagementHostPage.tsx index 526667a31..dedc41084 100644 --- a/apps/edr-freight-web/backoffice/src/pages/dashboard/user-management/UserManagementHostPage.tsx +++ b/apps/edr-freight-web/backoffice/src/pages/dashboard/user-management/UserManagementHostPage.tsx @@ -1,113 +1,82 @@ -import { useEffect, useRef, useState } from 'react'; -import { useNavigate, useLocation } from 'react-router-dom'; -import { getCookie } from '@/auth/cookies'; +import { useEffect, useRef } from "react"; +import { createRoot, type Root } from "react-dom/client"; +import { + UserManagementApp, + type UserManagementRuntimeOptions, + type UserManagementSessionSeed, +} from "@tria-plc/iamui"; -function readToken(): string | null { - return getCookie('auth-token') ?? null; -} +import { getCookie } from "@/auth/cookies"; -function readRefreshToken(): string | null { - return getCookie('refresh-token') ?? null; +import { iamConfig } from "./iamConfig"; + +function readInitialSession(): UserManagementSessionSeed | null { + const token = getCookie("auth-token"); + + if (!token) { + return null; + } + + const refreshToken = getCookie("refresh-token") ?? undefined; + + return { + token, + refreshToken, + rememberMe: true, + }; } export default function UserManagementHostPage() { - const navigate = useNavigate(); - const location = useLocation(); - const iframeRef = useRef(null); + const mountRef = useRef(null); + const rootRef = useRef(null); + const unmountTimerRef = useRef(null); - const mountBase = ( - (import.meta.env.VITE_USER_MANAGEMENT_BASE as string | undefined) ?? '/_um' - ).replace(/\/$/, ''); - - const moduleOrigin = window.location.origin; - - const [iframeSrc] = useState(() => { - const sub = location.pathname.replace(/^\/(?:dashboard\/)?um(?=\/|$)/, ''); - return mountBase + (sub || '/') + location.search; - }); - - // ✅ Send token when iframe loads - const handleIframeLoad = () => { - const token = readToken(); - const refreshToken = readRefreshToken(); - const target = iframeRef.current?.contentWindow; - - if (!token) { - console.warn('⚠️ No authentication token found'); - return; - } - - if (!target) { - console.warn('⚠️ No iframe reference'); - return; - } - - target.postMessage( - { - type: 'UM_AUTH_TOKEN', - token, - refreshToken, - }, - moduleOrigin - ); - - console.log('✅ Token sent to iframe module'); - }; - - // ✅ Listen for messages from iframe useEffect(() => { - const onMessage = (event: MessageEvent) => { - // Security: Only accept from same origin - if (event.origin !== moduleOrigin) { - console.warn('🚫 Blocked message from different origin:', event.origin); - return; - } + const mountNode = mountRef.current; - const data = event.data as { type?: string; path?: string } | undefined; - if (!data) return; + if (!mountNode) { + return; + } - // Handle auth request (if module asks for token again) - if (data.type === 'UM_REQUEST_AUTH') { - const token = readToken(); - const refreshToken = readRefreshToken(); - const target = iframeRef.current?.contentWindow; + if (unmountTimerRef.current !== null) { + window.clearTimeout(unmountTimerRef.current); + unmountTimerRef.current = null; + } - if (token && target) { - target.postMessage( - { - type: 'UM_AUTH_TOKEN', - token, - refreshToken, - }, - moduleOrigin - ); - console.log('✅ Token resent to iframe (on request)'); - } - return; - } + if (!rootRef.current) { + rootRef.current = createRoot(mountNode); + } - // Handle route synchronization - if (data.type === 'UM_ROUTE_CHANGED' && typeof data.path === 'string') { - const target = '/dashboard/um' + data.path; - if (window.location.pathname + window.location.search !== target) { - navigate(target, { replace: true }); - } - } + const apiBaseUrl = import.meta.env.VITE_BASE_API_URL.replace(/\/+$/, ""); + const iamApiUrl = "/um-api"; + const runtime: UserManagementRuntimeOptions = { + basename: "/um", + apiBaseUrl, + apiUrl: iamApiUrl, + recordApiUrl: iamApiUrl, + chronicleUrl: iamApiUrl, + auditApiUrl: iamApiUrl, }; - window.addEventListener('message', onMessage); - return () => window.removeEventListener('message', onMessage); - }, [moduleOrigin, navigate]); + rootRef.current.render( + , + ); - return ( -
-