Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32209499
D15093.1765126534.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D15093.1765126534.diff
View Options
diff --git a/lib/components/farcaster-data-handler.react.js b/lib/components/farcaster-data-handler.react.js
--- a/lib/components/farcaster-data-handler.react.js
+++ b/lib/components/farcaster-data-handler.react.js
@@ -15,6 +15,7 @@
useCurrentUserFID,
useUnlinkFID,
useSetLocalFID,
+ useSetLocalCurrentUserSupportsDCs,
} from '../utils/farcaster-utils.js';
import { useDispatchActionPromise } from '../utils/redux-promise-utils.js';
import { useSelector, useDispatch } from '../utils/redux-utils.js';
@@ -157,6 +158,8 @@
const [fidLoaded, setFIDLoaded] = React.useState(false);
const setLocalFID = useSetLocalFID();
+ const setLocalDCsSupport = useSetLocalCurrentUserSupportsDCs();
+
const handleCurrentUserFID = React.useCallback(async () => {
if (
canQueryHandleCurrentUserFID ===
@@ -178,6 +181,10 @@
? false
: getCachedUserIdentity(currentUserID) === undefined;
+ if (userIdentities[currentUserID]) {
+ setLocalDCsSupport(userIdentities[currentUserID].hasFarcasterDCsToken);
+ }
+
if (fid && !identityFIDRequestTimedOut && fid !== identityFID) {
setLocalFID(identityFID);
return;
@@ -204,6 +211,7 @@
unlinkFID,
setLocalFID,
getCachedUserIdentity,
+ setLocalDCsSupport,
]);
React.useEffect(() => {
diff --git a/lib/tunnelbroker/use-peer-to-peer-message-handler.js b/lib/tunnelbroker/use-peer-to-peer-message-handler.js
--- a/lib/tunnelbroker/use-peer-to-peer-message-handler.js
+++ b/lib/tunnelbroker/use-peer-to-peer-message-handler.js
@@ -51,6 +51,10 @@
import { getConfig } from '../utils/config.js';
import { getContentSigningKey } from '../utils/crypto-utils.js';
import { getMessageForException } from '../utils/errors.js';
+import {
+ useSetLocalCurrentUserSupportsDCs,
+ useSetLocalFID,
+} from '../utils/farcaster-utils.js';
import {
hasHigherDeviceID,
OLM_ERROR_FLAG,
@@ -99,6 +103,9 @@
const { userDataRestore } = useUserDataRestoreContext();
const restoreBackupState = useSelector(state => state.restoreBackupState);
+ const setLocalFID = useSetLocalFID();
+ const setLocalDCsSupport = useSetLocalCurrentUserSupportsDCs();
+
return React.useCallback(
async (
decryptedMessageContent: string,
@@ -208,6 +215,12 @@
await userDataRestore(false, userID, accessToken, backupData);
await sqliteAPI.removeInboundP2PMessages([messageID]);
+ } else if (
+ userActionMessage.type ===
+ userActionsP2PMessageTypes.FARCASTER_CONNECTION_UPDATED
+ ) {
+ setLocalFID(userActionMessage.farcasterID);
+ setLocalDCsSupport(userActionMessage.hasDCsToken);
} else {
console.warn(
'Unsupported P2P user action message:',
@@ -224,6 +237,8 @@
reBroadcastAccountDeletion,
restoreBackupState.status,
runDeviceListUpdate,
+ setLocalDCsSupport,
+ setLocalFID,
userDataRestore,
],
);
diff --git a/lib/types/tunnelbroker/peer-to-peer-message-types.js b/lib/types/tunnelbroker/peer-to-peer-message-types.js
--- a/lib/types/tunnelbroker/peer-to-peer-message-types.js
+++ b/lib/types/tunnelbroker/peer-to-peer-message-types.js
@@ -116,7 +116,7 @@
};
export const badDeviceTokenValidator: TInterface<BadDeviceToken> =
tShape<BadDeviceToken>({
- type: tString('BadDeviceToken'),
+ type: tString(peerToPeerMessageTypes.BAD_DEVICE_TOKEN),
invalidatedToken: t.String,
});
diff --git a/lib/types/tunnelbroker/user-actions-peer-to-peer-message-types.js b/lib/types/tunnelbroker/user-actions-peer-to-peer-message-types.js
--- a/lib/types/tunnelbroker/user-actions-peer-to-peer-message-types.js
+++ b/lib/types/tunnelbroker/user-actions-peer-to-peer-message-types.js
@@ -13,6 +13,7 @@
ACCOUNT_DELETION: 'ACCOUNT_DELETION',
DM_OPERATION: 'DM_OPERATION',
BACKUP_DATA: 'BACKUP_DATA',
+ FARCASTER_CONNECTION_UPDATED: 'FARCASTER_CONNECTION_UPDATED',
});
export type DeviceLogoutP2PMessage = {
@@ -66,12 +67,25 @@
backupData: t.maybe(qrAuthBackupDataValidator),
});
+export type FarcasterConnectionUpdated = {
+ +type: 'FARCASTER_CONNECTION_UPDATED',
+ +farcasterID: ?string,
+ +hasDCsToken: ?boolean,
+};
+export const farcasterConnectionUpdatedValidator: TInterface<FarcasterConnectionUpdated> =
+ tShape<FarcasterConnectionUpdated>({
+ type: tString(userActionsP2PMessageTypes.FARCASTER_CONNECTION_UPDATED),
+ farcasterID: t.maybe(t.String),
+ hasDCsToken: t.maybe(t.Boolean),
+ });
+
export type UserActionP2PMessage =
| DeviceLogoutP2PMessage
| SecondaryDeviceLogoutP2PMessage
| AccountDeletionP2PMessage
| DMOperationP2PMessage
- | BackupDataP2PMessage;
+ | BackupDataP2PMessage
+ | FarcasterConnectionUpdated;
export const userActionP2PMessageValidator: TUnion<UserActionP2PMessage> =
t.union([
@@ -80,4 +94,5 @@
accountDeletionP2PMessageValidator,
dmOperationP2PMessageValidator,
backupDataP2PMessageValidator,
+ farcasterConnectionUpdatedValidator,
]);
diff --git a/lib/utils/farcaster-utils.js b/lib/utils/farcaster-utils.js
--- a/lib/utils/farcaster-utils.js
+++ b/lib/utils/farcaster-utils.js
@@ -2,12 +2,20 @@
import invariant from 'invariant';
import * as React from 'react';
+import uuid from 'uuid';
+import { getConfig } from './config.js';
+import { getContentSigningKey } from './crypto-utils.js';
import { useSelector, useDispatch } from './redux-utils.js';
import { setSyncedMetadataEntryActionType } from '../actions/synced-metadata-actions.js';
import { useUserIdentityCache } from '../components/user-identity-cache.react.js';
+import { getOwnPeerDevices } from '../selectors/user-selectors.js';
import { IdentityClientContext } from '../shared/identity-client-context.js';
+import { PeerToPeerContext } from '../tunnelbroker/peer-to-peer-context.js';
+import { databaseIdentifier } from '../types/database-identifier-types.js';
+import { outboundP2PMessageStatuses } from '../types/sqlite-types.js';
import { syncedMetadataNames } from '../types/synced-metadata-types.js';
+import type { FarcasterConnectionUpdated } from '../types/tunnelbroker/user-actions-peer-to-peer-message-types.js';
const DISABLE_CONNECT_FARCASTER_ALERT = false;
const NO_FID_METADATA = 'NONE';
@@ -108,13 +116,16 @@
const { linkFarcasterAccount } = identityClient;
const setLocalFID = useSetLocalFID();
+ const broadcastConnectionStatus =
+ useBroadcastUpdateFarcasterConnectionStatus();
return React.useCallback(
async (fid: string) => {
await linkFarcasterAccount(fid);
setLocalFID(fid);
+ await broadcastConnectionStatus(fid, null);
},
- [setLocalFID, linkFarcasterAccount],
+ [linkFarcasterAccount, setLocalFID, broadcastConnectionStatus],
);
}
@@ -127,12 +138,20 @@
const setLocalFID = useSetLocalFID();
const setLocalDCsSupport = useSetLocalCurrentUserSupportsDCs();
+ const broadcastConnectionStatus =
+ useBroadcastUpdateFarcasterConnectionStatus();
return React.useCallback(async () => {
await unlinkFarcasterAccount();
setLocalFID(null);
setLocalDCsSupport(null);
- }, [setLocalFID, setLocalDCsSupport, unlinkFarcasterAccount]);
+ await broadcastConnectionStatus(null, null);
+ }, [
+ unlinkFarcasterAccount,
+ setLocalFID,
+ setLocalDCsSupport,
+ broadcastConnectionStatus,
+ ]);
}
function useLinkFarcasterDCs(): (
@@ -146,13 +165,60 @@
const { linkFarcasterDCsAccount } = identityClient;
const setLocalDCsSupport = useSetLocalCurrentUserSupportsDCs();
+ const broadcastConnectionStatus =
+ useBroadcastUpdateFarcasterConnectionStatus();
return React.useCallback(
async (fid: string, farcasterDCsToken: string) => {
await linkFarcasterDCsAccount(fid, farcasterDCsToken);
setLocalDCsSupport(true);
+ await broadcastConnectionStatus(fid, true);
},
- [setLocalDCsSupport, linkFarcasterDCsAccount],
+ [linkFarcasterDCsAccount, setLocalDCsSupport, broadcastConnectionStatus],
+ );
+}
+
+function useBroadcastUpdateFarcasterConnectionStatus() {
+ const peerToPeerContext = React.useContext(PeerToPeerContext);
+ const { processDBStoreOperations } = getConfig().sqliteAPI;
+
+ const currentUserID = useSelector(state => state.currentUserInfo?.id);
+ const userDevices = useSelector(getOwnPeerDevices);
+ return React.useCallback(
+ async (farcasterID: ?string, hasDCsToken: ?boolean) => {
+ if (!currentUserID) {
+ return;
+ }
+ invariant(peerToPeerContext, 'PeerToPeerContext should be set');
+ const thisDeviceID = await getContentSigningKey();
+ const message: FarcasterConnectionUpdated = {
+ type: 'FARCASTER_CONNECTION_UPDATED',
+ farcasterID,
+ hasDCsToken,
+ };
+ const messageString = JSON.stringify(message);
+ const timestamp = new Date().getTime().toString();
+ const messages = userDevices
+ .filter(device => device.deviceID !== thisDeviceID)
+ .map(device => ({
+ messageID: uuid.v4(),
+ deviceID: device.deviceID,
+ userID: currentUserID,
+ timestamp,
+ plaintext: messageString,
+ ciphertext: '',
+ status: outboundP2PMessageStatuses.persisted,
+ supportsAutoRetry: true,
+ }));
+ await processDBStoreOperations(
+ { outboundP2PMessages: messages },
+ databaseIdentifier.MAIN,
+ );
+ await peerToPeerContext.processOutboundMessages(
+ messages.map(m => m.messageID),
+ );
+ },
+ [currentUserID, peerToPeerContext, processDBStoreOperations, userDevices],
);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Dec 7, 4:55 PM (17 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5845112
Default Alt Text
D15093.1765126534.diff (9 KB)
Attached To
Mode
D15093: [lib] Inform other own devices about the connection update
Attached
Detach File
Event Timeline
Log In to Comment