Skip to content

Commit

Permalink
refactor(#141): [wip] enable multiple action receivers
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyckahn committed Dec 2, 2024
1 parent 1318e58 commit 6b587e1
Show file tree
Hide file tree
Showing 10 changed files with 461 additions and 326 deletions.
132 changes: 66 additions & 66 deletions src/components/Room/usePeerVerification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,89 @@ import { ShellContext } from 'contexts/ShellContext'
import { Peer, PeerVerificationState } from 'models/chat'
import { encryption } from 'services/Encryption'
import { PeerRoom } from 'lib/PeerRoom'
import { groupActionNamespace, PeerAction } from 'models/network'
import { PeerAction } from 'models/network'
import { verificationTimeout } from 'config/messaging'
import { usePeerNameDisplay } from 'components/PeerNameDisplay'
import { usePeerAction } from 'hooks/usePeerAction'

interface UserPeerVerificationProps {
peerRoom: PeerRoom
privateKey: CryptoKey
isDirectMessageRoom: boolean
encryptionService?: typeof encryption
}

export const usePeerVerification = ({
peerRoom,
privateKey,
isDirectMessageRoom,
encryptionService = encryption,
}: UserPeerVerificationProps) => {
const { updatePeer, peerList, showAlert } = useContext(ShellContext)
const namespace = isDirectMessageRoom ? 'dm' : 'g'

const { getDisplayUsername } = usePeerNameDisplay()

const [sendVerificationTokenEncrypted, receiveVerificationTokenEncrypted] =
peerRoom.makeAction<ArrayBuffer>(
PeerAction.VERIFICATION_TOKEN_ENCRYPTED,
groupActionNamespace
)
const [sendVerificationTokenEncrypted] = usePeerAction<ArrayBuffer>({
peerAction: PeerAction.VERIFICATION_TOKEN_ENCRYPTED,
peerRoom,
namespace,
onReceive: async (encryptedVerificationToken, peerId) => {
try {
const decryptedVerificationToken =
await encryptionService.decryptString(
privateKey,
encryptedVerificationToken
)

await sendVerificationTokenRaw(decryptedVerificationToken, [peerId])
} catch (e) {
console.error(e)
}
},
})

const [sendVerificationTokenRaw] = usePeerAction<string>({
peerAction: PeerAction.VERIFICATION_TOKEN_RAW,
peerRoom,
namespace,
onReceive: (decryptedVerificationToken, peerId) => {
const matchingPeer = peerList.find(peer => peer.peerId === peerId)

if (!matchingPeer) {
throw new Error(`peerId not found: ${peerId}`)
}

const { verificationToken, verificationTimer } = matchingPeer

if (decryptedVerificationToken !== verificationToken) {
updatePeer(peerId, {
verificationState: PeerVerificationState.UNVERIFIED,
verificationTimer: null,
})

showAlert(
`Verification for ${getDisplayUsername(matchingPeer.userId)} failed`,
{
severity: 'error',
}
)

throw new Error(
`Verification token for peerId ${peerId} does not match. [expected: ${verificationToken}] [received: ${decryptedVerificationToken}]`
)
}

if (verificationTimer) {
clearTimeout(verificationTimer)
}

const [sendVerificationTokenRaw, receiveVerificationTokenRaw] =
peerRoom.makeAction<string>(
PeerAction.VERIFICATION_TOKEN_RAW,
groupActionNamespace
)
updatePeer(peerId, {
verificationState: PeerVerificationState.VERIFIED,
verificationTimer: null,
})
},
})

const initPeerVerification = useCallback(
async (peer: Peer) => {
Expand Down Expand Up @@ -82,69 +135,16 @@ export const usePeerVerification = ({
const [scheduledPeerToVerify, setScheduledPeerToVerify] =
useState<Peer | null>(null)
useEffect(() => {
if (scheduledPeerToVerify === null) return
if (scheduledPeerToVerify === null || isDirectMessageRoom) return

initPeerVerification(scheduledPeerToVerify)
setScheduledPeerToVerify(null)
}, [scheduledPeerToVerify, initPeerVerification])
}, [scheduledPeerToVerify, initPeerVerification, isDirectMessageRoom])
// NOTE: END HACKY WORKAROUND

const verifyPeer = (peer: Peer) => {
setScheduledPeerToVerify(peer)
}

receiveVerificationTokenEncrypted(
async (encryptedVerificationToken, peerId) => {
try {
const decryptedVerificationToken =
await encryptionService.decryptString(
privateKey,
encryptedVerificationToken
)

await sendVerificationTokenRaw(decryptedVerificationToken, [peerId])
} catch (e) {
console.error(e)
}
}
)

receiveVerificationTokenRaw((decryptedVerificationToken, peerId) => {
const matchingPeer = peerList.find(peer => peer.peerId === peerId)

if (!matchingPeer) {
throw new Error(`peerId not found: ${peerId}`)
}

const { verificationToken, verificationTimer } = matchingPeer

if (decryptedVerificationToken !== verificationToken) {
updatePeer(peerId, {
verificationState: PeerVerificationState.UNVERIFIED,
verificationTimer: null,
})

showAlert(
`Verification for ${getDisplayUsername(matchingPeer.userId)} failed`,
{
severity: 'error',
}
)

throw new Error(
`Verification token for peerId ${peerId} does not match. [expected: ${verificationToken}] [received: ${decryptedVerificationToken}]`
)
}

if (verificationTimer) {
clearTimeout(verificationTimer)
}

updatePeer(peerId, {
verificationState: PeerVerificationState.VERIFIED,
verificationTimer: null,
})
})

return { verifyPeer }
}
Loading

0 comments on commit 6b587e1

Please sign in to comment.