Files
cinny/src/app/hooks/useKeyBackup.ts
T

161 lines
3.7 KiB
TypeScript
Raw Normal View History

import {
BackupTrustInfo,
CryptoApi,
CryptoEvent,
CryptoEventHandlerMap,
KeyBackupInfo,
} from 'matrix-js-sdk/lib/crypto-api';
import { useCallback, useEffect, useState } from 'react';
import { useMatrixClient } from './useMatrixClient';
import { useAlive } from './useAlive';
export const useKeyBackupStatusChange = (
onChange: CryptoEventHandlerMap[CryptoEvent.KeyBackupStatus]
) => {
const mx = useMatrixClient();
useEffect(() => {
mx.on(CryptoEvent.KeyBackupStatus, onChange);
return () => {
mx.removeListener(CryptoEvent.KeyBackupStatus, onChange);
};
}, [mx, onChange]);
};
export const useKeyBackupStatus = (crypto: CryptoApi): boolean => {
const alive = useAlive();
const [status, setStatus] = useState(false);
useEffect(() => {
crypto.getActiveSessionBackupVersion().then((v) => {
if (alive()) {
setStatus(typeof v === 'string');
}
});
}, [crypto, alive]);
useKeyBackupStatusChange(setStatus);
return status;
};
export const useKeyBackupSessionsRemainingChange = (
onChange: CryptoEventHandlerMap[CryptoEvent.KeyBackupSessionsRemaining]
) => {
const mx = useMatrixClient();
useEffect(() => {
mx.on(CryptoEvent.KeyBackupSessionsRemaining, onChange);
return () => {
mx.removeListener(CryptoEvent.KeyBackupSessionsRemaining, onChange);
};
}, [mx, onChange]);
};
export const useKeyBackupFailedChange = (
onChange: CryptoEventHandlerMap[CryptoEvent.KeyBackupFailed]
) => {
const mx = useMatrixClient();
useEffect(() => {
mx.on(CryptoEvent.KeyBackupFailed, onChange);
return () => {
mx.removeListener(CryptoEvent.KeyBackupFailed, onChange);
};
}, [mx, onChange]);
};
export const useKeyBackupDecryptionKeyCached = (
onChange: CryptoEventHandlerMap[CryptoEvent.KeyBackupDecryptionKeyCached]
) => {
const mx = useMatrixClient();
useEffect(() => {
mx.on(CryptoEvent.KeyBackupDecryptionKeyCached, onChange);
return () => {
mx.removeListener(CryptoEvent.KeyBackupDecryptionKeyCached, onChange);
};
}, [mx, onChange]);
};
export const useKeyBackupSync = (): [number, string | undefined] => {
const [remaining, setRemaining] = useState(0);
const [failure, setFailure] = useState<string>();
useKeyBackupSessionsRemainingChange(
useCallback((count) => {
setRemaining(count);
setFailure(undefined);
}, [])
);
useKeyBackupFailedChange(
useCallback((f) => {
if (typeof f === 'string') {
setFailure(f);
setRemaining(0);
}
}, [])
);
return [remaining, failure];
};
export const useKeyBackupInfo = (crypto: CryptoApi): KeyBackupInfo | undefined | null => {
const alive = useAlive();
const [info, setInfo] = useState<KeyBackupInfo | null>();
const fetchInfo = useCallback(() => {
crypto.getKeyBackupInfo().then((i) => {
if (alive()) {
setInfo(i);
}
});
}, [crypto, alive]);
useEffect(() => {
fetchInfo();
}, [fetchInfo]);
useKeyBackupStatusChange(fetchInfo);
useKeyBackupSessionsRemainingChange(
useCallback(
(remainingCount) => {
if (remainingCount === 0) {
fetchInfo();
}
},
[fetchInfo]
)
);
return info;
};
export const useKeyBackupTrust = (
crypto: CryptoApi,
backupInfo: KeyBackupInfo
): BackupTrustInfo | undefined => {
const alive = useAlive();
const [trust, setTrust] = useState<BackupTrustInfo>();
const fetchTrust = useCallback(() => {
crypto.isKeyBackupTrusted(backupInfo).then((t) => {
if (alive()) {
setTrust(t);
}
});
}, [crypto, alive, backupInfo]);
useEffect(() => {
fetchTrust();
}, [fetchTrust]);
useKeyBackupStatusChange(fetchTrust);
useKeyBackupDecryptionKeyCached(fetchTrust);
return trust;
};