Skip to content
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
49 changes: 48 additions & 1 deletion webui/src/components/pages/dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,55 @@ export function Dashboard() {
{/* Two equal columns: CryoEM Facilities and SmartEM Application */}
<Box sx={{ display: 'flex', flexDirection: 'row', flex: 1, gap: 3 }}>
{/* CryoEM Facilities */}
<Box sx={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 1 }}>
<Box sx={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 2.5 }}>
<MicroscopeGrid />
<Box
data-connection-id="dls-keycloak"
sx={{ display: 'flex', flexDirection: 'column' }}
>
<SystemComponentContainer heading="DLS Keycloak">
<Box sx={{ ...itemBoxSx, display: 'flex', flexDirection: 'column', gap: 0.5 }}>
<Typography variant="caption" sx={{ color: '#333', fontWeight: 500 }}>
Realm: dls
</Typography>
<Typography
variant="caption"
component="div"
sx={{ color: '#555', fontSize: '0.65rem', fontFamily: 'monospace' }}
>
Production:{' '}
<Link href="https://identity.diamond.ac.uk" target="_blank" rel="noopener">
https://identity.diamond.ac.uk
</Link>
<br />
Test:{' '}
<Link
href="https://identity-test.diamond.ac.uk"
target="_blank"
rel="noopener"
>
https://identity-test.diamond.ac.uk
</Link>
</Typography>

<Typography variant="caption" sx={{ color: '#333', fontWeight: 500, mt: 1 }}>
Clients
</Typography>
<Typography
variant="caption"
component="div"
sx={{ color: '#555', fontSize: '0.65rem', fontFamily: 'monospace' }}
>
- SmartEM_User (public, OIDC authorization code + PKCE)
<br />- SmartEM_Agent (confidential, OAuth 2.0 client_credentials)
<br />
Backend validates Bearer tokens against JWKS.
<br />
See ADR 0018 for the agent auth design.
</Typography>
</Box>
</SystemComponentContainer>
</Box>
</Box>

{/* SmartEM Application */}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ export function ConnectionsOverlay({ connections, containerRef }: ConnectionsOve
d={pathD}
stroke={conn.color}
strokeWidth={2}
strokeDasharray={conn.strokeDasharray}
fill="none"
style={{ pointerEvents: 'none' }}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export function MicroscopeGrid() {
display: 'flex',
flexDirection: 'column',
gap: 7,
flex: 1,
}}
>
{detailed.map((instrument) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export interface Connection {
sourceDotOffset?: number // Offset along the edge for source dot (positive = right/down)
targetDotOffset?: number // Offset along the edge for target dot (positive = right/down)
arrow?: 'source' | 'target' | 'both' | 'none' // Arrow direction (default: 'none')
// Trust/identity edges (e.g. auth flows) use a dashed stroke so they read
// as a different kind of edge from data/RPC paths.
strokeDasharray?: string
}

// Color palette for connections
Expand All @@ -21,6 +24,7 @@ const colors = {
purple: '#9c27b0', // C3: Agent -> Athena API (microscope control)
teal: '#009688', // C4: ARIA Connector flows
pink: '#e91e63', // C5: Web UI -> Backend API
gold: '#b8860b', // Auth: Keycloak trust/identity edges (rendered dashed)
}

export const dashboardConnections: Connection[] = [
Expand Down Expand Up @@ -125,4 +129,52 @@ export const dashboardConnections: Connection[] = [
curveOffset: 90, // More curvature for pink connection
arrow: 'source', // Arrow pointing to Web UI (data flows from API to UI)
},
// C6: Auth — SmartEM Web UI -> DLS Keycloak (OIDC authorization code + PKCE)
// Keycloak sits in the left column under the microscope grid; UI is in the
// middle column, so the edge runs leftward.
{
id: 'webui-to-keycloak',
sourceId: 'smartem-webui',
targetId: 'dls-keycloak',
sourceAnchor: 'left',
targetAnchor: 'right',
color: colors.gold,
tooltip:
'SmartEM Web UI authenticates users against DLS Keycloak via OIDC authorization code flow with PKCE (SmartEM_User client)',
strokeDasharray: '6 4',
sourceDotOffset: -10,
arrow: 'target',
},
// C6: Auth — SmartEM Agent -> DLS Keycloak (client_credentials grant)
// Both live in the left column with Keycloak below the microscope grid.
// Endpoints are nudged right of column-centre so the line runs alongside
// the "+N more microscopes" stack without overlapping its centred text+icon.
{
id: 'agent-to-keycloak',
sourceId: 'smartem-agent',
targetId: 'dls-keycloak',
sourceAnchor: 'bottom',
targetAnchor: 'top',
color: colors.gold,
tooltip:
'SmartEM Agent obtains service-account tokens from DLS Keycloak via OAuth 2.0 client_credentials grant (SmartEM_Agent client). See ADR 0018.',
strokeDasharray: '6 4',
sourceDotOffset: 60,
targetDotOffset: 130,
arrow: 'target',
},
// C6: Auth — SmartEM Backend API -> DLS Keycloak (JWKS for Bearer-token validation)
{
id: 'backend-to-keycloak',
sourceId: 'smartem-backend-api',
targetId: 'dls-keycloak',
sourceAnchor: 'left',
targetAnchor: 'right',
color: colors.gold,
tooltip:
'SmartEM Backend validates incoming Bearer tokens (from Web UI and Agent) against the DLS Keycloak JWKS endpoint',
strokeDasharray: '6 4',
sourceDotOffset: -10,
arrow: 'target',
},
]