Compare commits

...

2 Commits

@@ -1,6 +1,7 @@
import Alert from '@mui/material/Alert' import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
import Button from '@mui/material/Button' import Button from '@mui/material/Button'
import Chip from '@mui/material/Chip'
import Dialog from '../components/ModalDialog' import Dialog from '../components/ModalDialog'
import DialogActions from '@mui/material/DialogActions' import DialogActions from '@mui/material/DialogActions'
import DialogTitle from '@mui/material/DialogTitle' import DialogTitle from '@mui/material/DialogTitle'
@@ -118,6 +119,8 @@ export default function AdminSSHAccessProfilesPage() {
item.server_group_id, item.server_group_id,
item.remote_username, item.remote_username,
item.auth_method, item.auth_method,
item.owner_scope,
item.owner_user_id,
item.auth_public_key_fingerprint, item.auth_public_key_fingerprint,
item.ssh_user_ca_id, item.ssh_user_ca_id,
(item.ssh_principal_grant_ids || []).join(' '), (item.ssh_principal_grant_ids || []).join(' '),
@@ -132,6 +135,14 @@ export default function AdminSSHAccessProfilesPage() {
const userOptions = useMemo(() => users.filter((item) => !item.disabled), [users]) const userOptions = useMemo(() => users.filter((item) => !item.disabled), [users])
const groupOptions = useMemo(() => groups.filter((item) => !item.disabled), [groups]) const groupOptions = useMemo(() => groups.filter((item) => !item.disabled), [groups])
const caOptions = useMemo(() => cas.filter((item) => item.enabled), [cas]) const caOptions = useMemo(() => cas.filter((item) => item.enabled), [cas])
const userNameByID = useMemo(() => {
const map: Record<string, string> = {}
users.forEach((item: User) => {
map[item.id] = item.display_name ? `${item.display_name} (${item.username})` : item.username
})
return map
}, [users])
const caNameByID = useMemo(() => { const caNameByID = useMemo(() => {
const map: Record<string, string> = {} const map: Record<string, string> = {}
@@ -399,7 +410,14 @@ export default function AdminSSHAccessProfilesPage() {
<ListItem key={item.id} divider sx={{ alignItems: 'flex-start' }}> <ListItem key={item.id} divider sx={{ alignItems: 'flex-start' }}>
<CompactListItemText <CompactListItemText
primary={ primary={
<Typography>{item.name}</Typography> <Typography>
{item.name}{' '}
<Chip
size="small"
label={item.owner_scope === 'user' ? 'Self-Service' : 'Admin'}
color={item.owner_scope === 'user' ? 'info' : 'default'}
/>
</Typography>
} }
secondary={ secondary={
<Box sx={{ display: 'grid' }}> <Box sx={{ display: 'grid' }}>
@@ -428,7 +446,9 @@ export default function AdminSSHAccessProfilesPage() {
{item.server_target_type === 'group' ? '' : ` · ${item.server?.host}:${item.server?.port}`} · {item.remote_username} · {item.auth_method} · 2FA: {item.second_factor_mode || 'none'} · {item.enabled ? 'enabled' : 'disabled'} {item.server_target_type === 'group' ? '' : ` · ${item.server?.host}:${item.server?.port}`} · {item.remote_username} · {item.auth_method} · 2FA: {item.second_factor_mode || 'none'} · {item.enabled ? 'enabled' : 'disabled'}
</Typography> </Typography>
<Typography variant="caption" color="text.secondary" sx={{ wordBreak: 'break-word' }}> <Typography variant="caption" color="text.secondary" sx={{ wordBreak: 'break-word' }}>
Targets: {(item.targets || []).map((target) => `${target.target_type}:${target.target_name}`).join(', ') || '-'} {item.owner_scope === 'user'
? `Owner: ${userNameByID[item.owner_user_id] || item.owner_user_id || '-'} · Targets: owner only`
: `Targets: ${(item.targets || []).map((target) => `${target.target_type}:${target.target_name}`).join(', ') || '-'}`}
</Typography> </Typography>
{item.auth_method === 'managed_ssh_cert' ? ( {item.auth_method === 'managed_ssh_cert' ? (
<Typography variant="caption" color="text.secondary" sx={{ wordBreak: 'break-word' }}> <Typography variant="caption" color="text.secondary" sx={{ wordBreak: 'break-word' }}>
@@ -467,7 +487,9 @@ export default function AdminSSHAccessProfilesPage() {
/> />
<ListRowActions> <ListRowActions>
<ListRowActionButton onClick={() => setViewItem(item)}>View</ListRowActionButton> <ListRowActionButton onClick={() => setViewItem(item)}>View</ListRowActionButton>
<ListRowActionButton onClick={() => openEdit(item)}>Edit</ListRowActionButton> {item.owner_scope === 'user' ? null : (
<ListRowActionButton onClick={() => openEdit(item)}>Edit</ListRowActionButton>
)}
<ListRowActionButton color="error" onClick={() => { setDeleteItem(item); setDeleteConfirm('') }}> <ListRowActionButton color="error" onClick={() => { setDeleteItem(item); setDeleteConfirm('') }}>
Delete Delete
</ListRowActionButton> </ListRowActionButton>