| undefined
- const trustLevel = getTrustLevelFromAttributes(participantAttrs, roomData?.encryption_mode)
+ const { trustLevel, fingerprintStatus, fingerprint: participantFingerprint } = useParticipantTrustLevel(participantAttrs, roomData?.encryption_mode, trackReference.participant.isLocal)
const { t: tBadge } = useTranslation('rooms', { keyPrefix: 'encryption.badge' })
- const badgeTooltip = trustLevel ? tBadge(trustLevel) : undefined
+ const badgeTooltip = tBadge(trustLevel)
// Track decryption failures via EncryptionError events from LiveKit.
// useIsEncrypted returns true when E2EE is enabled, NOT when frames decrypt successfully.
@@ -331,7 +331,7 @@ export const ParticipantTile: (
}}
/>
)}
- {isEncryptedRoom && isAdmin && !isScreenShare ? (
+ {isEncryptedRoom && !isScreenShare ? (
)}
@@ -406,15 +406,18 @@ export const ParticipantTile: (
),
})}
- {isEncryptedRoom && isAdmin && (
-
)}
diff --git a/src/frontend/src/features/rooms/livekit/components/controls/Participants/ParticipantListItem.tsx b/src/frontend/src/features/rooms/livekit/components/controls/Participants/ParticipantListItem.tsx
index 4d601caa..c472de00 100644
--- a/src/frontend/src/features/rooms/livekit/components/controls/Participants/ParticipantListItem.tsx
+++ b/src/frontend/src/features/rooms/livekit/components/controls/Participants/ParticipantListItem.tsx
@@ -21,7 +21,8 @@ import { useMuteParticipant } from '@/features/rooms/api/muteParticipant'
import { useCanMute } from '@/features/rooms/livekit/hooks/useCanMute'
import { ParticipantMenuButton } from '../../ParticipantMenu/ParticipantMenuButton'
import { PinBadge } from './PinBadge'
-import { EncryptionBadge, getTrustLevelFromAttributes, FingerprintDialog } from '@/features/encryption'
+import { EncryptionBadge, EncryptionIdentityDialog } from '@/features/encryption'
+import { useParticipantTrustLevel } from '@/features/encryption/useParticipantTrustLevel'
import { useRoomData } from '@/features/rooms/livekit/hooks/useRoomData'
import { isEncryptedRoom as isEncryptedRoomFn } from '@/features/rooms/api/ApiRoom'
import { useIsAdminOrOwner } from '@/features/rooms/livekit/hooks/useIsAdminOrOwner'
@@ -108,11 +109,11 @@ export const ParticipantListItem = ({
const isAdmin = useIsAdminOrOwner()
const { isLoggedIn } = useUser()
const { t: tEncBadge } = useTranslation('rooms', { keyPrefix: 'encryption.badge' })
- const [isFingerprintOpen, setIsFingerprintOpen] = useState(false)
+ const [isIdentityOpen, setIsFingerprintOpen] = useState(false)
const name = participant.name || participant.identity
const attrs = participant.attributes as Record | undefined
- const trustLevel = getTrustLevelFromAttributes(attrs, roomData?.encryption_mode)
- const badgeTooltip = trustLevel ? tEncBadge(trustLevel) : undefined
+ const { trustLevel, fingerprintStatus, fingerprint } = useParticipantTrustLevel(attrs, roomData?.encryption_mode, isLocal(participant))
+ const badgeTooltip = tEncBadge(trustLevel)
return (
setIsFingerprintOpen(true) : undefined}
+ onPress={() => setIsFingerprintOpen(true)}
className={css({
padding: '0.1rem 0.25rem !important',
minWidth: 'auto !important',
@@ -148,9 +149,9 @@ export const ParticipantListItem = ({
borderRadius: '0.25rem !important',
backgroundColor: 'transparent !important',
color: 'greyscale.900 !important',
- cursor: isAdmin ? 'pointer' : 'default',
+ cursor: isEncryptedRoom ? 'pointer' : 'default',
'&[data-hovered]': {
- backgroundColor: isAdmin ? 'greyscale.100 !important' : 'transparent !important',
+ backgroundColor: 'greyscale.100 !important',
},
})}
>
@@ -244,15 +245,18 @@ export const ParticipantListItem = ({
- {isEncryptedRoom && isAdmin && (
-
)}
diff --git a/src/frontend/src/features/rooms/livekit/components/controls/Participants/WaitingParticipantListItem.tsx b/src/frontend/src/features/rooms/livekit/components/controls/Participants/WaitingParticipantListItem.tsx
index 2391d1c5..62cec3cc 100644
--- a/src/frontend/src/features/rooms/livekit/components/controls/Participants/WaitingParticipantListItem.tsx
+++ b/src/frontend/src/features/rooms/livekit/components/controls/Participants/WaitingParticipantListItem.tsx
@@ -7,20 +7,10 @@ import { WaitingParticipant } from '@/features/rooms/api/listWaitingParticipants
import { RiCloseLine } from '@remixicon/react'
import { useRoomData } from '@/features/rooms/livekit/hooks/useRoomData'
import { isEncryptedRoom } from '@/features/rooms/api/ApiRoom'
-import { EncryptionBadge, getTrustLevelFromAttributes, FingerprintDialog } from '@/features/encryption'
-import type { TrustLevel } from '@/features/encryption/types'
+import { EncryptionBadge, EncryptionIdentityDialog } from '@/features/encryption'
+import { useParticipantTrustLevel, formatFingerprint } from '@/features/encryption/useParticipantTrustLevel'
import { useState } from 'react'
-function waitingParticipantTrustLevel(
- participant: WaitingParticipant,
- encryptionMode?: string,
-): TrustLevel {
- // In basic mode, no PKI — only authenticated or anonymous
- // In advanced mode, would check vault keys (but waiting participants haven't joined yet)
- if (participant.is_authenticated) return 'authenticated'
- return 'anonymous'
-}
-
export const WaitingParticipantListItem = ({
participant,
onAction,
@@ -32,8 +22,13 @@ export const WaitingParticipantListItem = ({
const roomData = useRoomData()
const encryptedRoom = isEncryptedRoom(roomData)
const { t: tBadge } = useTranslation('rooms', { keyPrefix: 'encryption.badge' })
- const [isDialogOpen, setIsDialogOpen] = useState(false)
- const trustLevel = waitingParticipantTrustLevel(participant, roomData?.encryption_mode)
+ const [isIdentityOpen, setIsDialogOpen] = useState(false)
+ // Build attributes-like object for the hook (waiting participants aren't in LiveKit yet)
+ const waitingAttrs = {
+ is_authenticated: participant.is_authenticated ? 'true' : 'false',
+ suite_user_id: participant.suite_user_id || '',
+ }
+ const { trustLevel, fingerprintStatus, fingerprint } = useParticipantTrustLevel(waitingAttrs, roomData?.encryption_mode)
const badgeTooltip = encryptedRoom ? tBadge(trustLevel) : undefined
return (
@@ -107,6 +102,24 @@ export const WaitingParticipantListItem = ({
{participant.username}