Page MenuHomePhabricator

D12638.diff
No OneTemporary

D12638.diff

diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js
--- a/lib/actions/user-actions.js
+++ b/lib/actions/user-actions.js
@@ -76,6 +76,7 @@
} from '../types/tunnelbroker/peer-to-peer-message-types.js';
import {
userActionsP2PMessageTypes,
+ type PrimaryDeviceLogoutP2PMessage,
type SecondaryDeviceLogoutP2PMessage,
} from '../types/tunnelbroker/user-actions-peer-to-peer-message-types.js';
import type {
@@ -253,11 +254,82 @@
});
function usePrimaryDeviceLogOut(): () => Promise<LogOutResult> {
+ const identityContext = React.useContext(IdentityClientContext);
+ if (!identityContext) {
+ throw new Error('Identity service client is not initialized');
+ }
+
+ const { sendMessage } = useTunnelbroker();
const broadcastDeviceListUpdates = useBroadcastDeviceListUpdates();
const foreignPeerDevices = useSelector(getForeignPeerDevices);
const logOut = useLogOut(primaryDeviceLogOutOptions);
return React.useCallback(async () => {
+ const { identityClient, getAuthMetadata } = identityContext;
+ const authMetadata = await getAuthMetadata();
+ const { userID, deviceID: thisDeviceID } = authMetadata;
+ if (!thisDeviceID || !userID) {
+ throw new Error('No auth metadata');
+ }
+ const {
+ devices: [primaryDeviceID, ...secondaryDevices],
+ } = await fetchLatestDeviceList(identityClient, userID);
+ if (thisDeviceID !== primaryDeviceID) {
+ throw new Error('Used primary device logout on a non-primary device');
+ }
+
+ // create and send Olm Tunnelbroker messages to secondaryDevices
+ const { olmAPI } = getConfig();
+ await olmAPI.initializeCryptoAccount();
+ const messageContents: PrimaryDeviceLogoutP2PMessage = {
+ type: userActionsP2PMessageTypes.LOG_OUT_PRIMARY_DEVICE,
+ };
+ for (const deviceID of secondaryDevices) {
+ try {
+ const encryptedData = await olmAPI.encrypt(
+ JSON.stringify(messageContents),
+ deviceID,
+ );
+ const encryptedMessage: EncryptedMessage = {
+ type: peerToPeerMessageTypes.ENCRYPTED_MESSAGE,
+ senderInfo: { deviceID: thisDeviceID, userID },
+ encryptedData,
+ };
+ await sendMessage({
+ deviceID,
+ payload: JSON.stringify(encryptedMessage),
+ });
+ } catch {
+ try {
+ await createOlmSessionWithPeer(
+ authMetadata,
+ identityClient,
+ sendMessage,
+ userID,
+ deviceID,
+ );
+ const encryptedData = await olmAPI.encrypt(
+ JSON.stringify(messageContents),
+ deviceID,
+ );
+ const encryptedMessage: EncryptedMessage = {
+ type: peerToPeerMessageTypes.ENCRYPTED_MESSAGE,
+ senderInfo: { deviceID: thisDeviceID, userID },
+ encryptedData,
+ };
+ await sendMessage({
+ deviceID,
+ payload: JSON.stringify(encryptedMessage),
+ });
+ } catch (err) {
+ console.warn(
+ `Error sending primary device logout message to device ${deviceID}:`,
+ err,
+ );
+ }
+ }
+ }
+
// - logOut() performs device list update by calling Identity RPC
// - broadcastDeviceListUpdates asks peers to download it from identity
// so we need to call them in this order to make sure peers have latest
@@ -267,7 +339,13 @@
const logOutResult = await logOut();
await broadcastDeviceListUpdates(foreignPeerDevices);
return logOutResult;
- }, [broadcastDeviceListUpdates, foreignPeerDevices, logOut]);
+ }, [
+ broadcastDeviceListUpdates,
+ foreignPeerDevices,
+ identityContext,
+ logOut,
+ sendMessage,
+ ]);
}
const secondaryDeviceLogOutOptions = Object.freeze({

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 25, 7:30 PM (21 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2580799
Default Alt Text
D12638.diff (3 KB)

Event Timeline