import { ShowSasCallbacks, VerificationPhase, VerificationRequest, Verifier, } from 'matrix-js-sdk/lib/crypto-api'; import React, { CSSProperties, useCallback, useEffect, useState } from 'react'; import { VerificationMethod } from 'matrix-js-sdk/lib/types'; import { Box, Button, config, Dialog, Header, Icon, IconButton, Icons, Overlay, OverlayBackdrop, OverlayCenter, Spinner, Text, } from 'folds'; import FocusTrap from 'focus-trap-react'; import { useVerificationRequestPhase, useVerificationRequestReceived, useVerifierCancel, useVerifierShowSas, } from '../hooks/useVerificationRequest'; import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback'; import { ContainerColor } from '../styles/ContainerColor.css'; const DialogHeaderStyles: CSSProperties = { padding: `0 ${config.space.S200} 0 ${config.space.S400}`, borderBottomWidth: config.borderWidth.B300, }; type WaitingMessageProps = { message: string; }; function WaitingMessage({ message }: WaitingMessageProps) { return ( {message} ); } type VerificationUnexpectedProps = { message: string; onClose: () => void }; function VerificationUnexpected({ message, onClose }: VerificationUnexpectedProps) { return ( {message} ); } function VerificationWaitAccept() { return ( Please accept the request from other device. ); } type VerificationAcceptProps = { onAccept: () => Promise; }; function VerificationAccept({ onAccept }: VerificationAcceptProps) { const [acceptState, accept] = useAsyncCallback(onAccept); const accepting = acceptState.status === AsyncStatus.Loading; return ( Click accept to start the verification process. ); } function VerificationWaitStart() { return ( Verification request has been accepted. ); } type VerificationStartProps = { onStart: () => Promise; }; function AutoVerificationStart({ onStart }: VerificationStartProps) { useEffect(() => { onStart(); }, [onStart]); return ( ); } function CompareEmoji({ sasData }: { sasData: ShowSasCallbacks }) { const [confirmState, confirm] = useAsyncCallback(useCallback(() => sasData.confirm(), [sasData])); const confirming = confirmState.status === AsyncStatus.Loading || confirmState.status === AsyncStatus.Success; return ( Confirm the emoji below are displayed on both devices, in the same order: {sasData.sas.emoji?.map(([emoji, name], index) => ( {emoji} {name} ))} ); } type SasVerificationProps = { verifier: Verifier; onCancel: () => void; }; function SasVerification({ verifier, onCancel }: SasVerificationProps) { const [sasData, setSasData] = useState(); useVerifierShowSas(verifier, setSasData); useVerifierCancel(verifier, onCancel); useEffect(() => { verifier.verify(); }, [verifier]); if (sasData) { return ; } return ( ); } type VerificationDoneProps = { onExit: () => void; }; function VerificationDone({ onExit }: VerificationDoneProps) { return (
Your device is verified.
); } type VerificationCanceledProps = { onClose: () => void; }; function VerificationCanceled({ onClose }: VerificationCanceledProps) { return ( Verification has been canceled. ); } type DeviceVerificationProps = { request: VerificationRequest; onExit: () => void; }; export function DeviceVerification({ request, onExit }: DeviceVerificationProps) { const phase = useVerificationRequestPhase(request); const handleCancel = useCallback(() => { if (request.phase !== VerificationPhase.Done && request.phase !== VerificationPhase.Cancelled) { request.cancel(); } onExit(); }, [request, onExit]); const handleAccept = useCallback(() => request.accept(), [request]); const handleStart = useCallback(async () => { await request.startVerification(VerificationMethod.Sas); }, [request]); return ( }>
Device Verification
{phase === VerificationPhase.Requested && (request.initiatedByMe ? ( ) : ( ))} {phase === VerificationPhase.Ready && (request.initiatedByMe ? ( ) : ( ))} {phase === VerificationPhase.Started && (request.verifier ? ( ) : ( ))} {phase === VerificationPhase.Done && } {phase === VerificationPhase.Cancelled && ( )}
); } export function ReceiveSelfDeviceVerification() { const [request, setRequest] = useState(); useVerificationRequestReceived(setRequest); const handleExit = useCallback(() => { setRequest(undefined); }, []); if (!request) return null; if (!request.isSelfVerification) { return null; } return ; }