From 99f4e4a6ccef098c932b9a0293b233707d8d5d60 Mon Sep 17 00:00:00 2001 From: xsanm Date: Thu, 28 Nov 2024 14:24:34 +0100 Subject: [PATCH] [native] allow password change only on primary device Summary: This was discussed in [ENG-8070](https://linear.app/comm/issue/ENG-8070/regenerate-backup-on-every-password-change#comment-c64a499b) Only the primary device should be able to change the password. Perhaps there was some alternative to keep this for a while and disable this after the user migrated to Signed Device Lists (v2), but this is not easy and probably there is no need to complicate just to keep it for a ~month and then remove. Hook with check was introduced in D14058 Depends on D14061, D14062 Test Plan: 1. On primary device button to change password is visible 2. On secondary device there is no button Reviewers: ashoat, varun Reviewed By: ashoat Subscribers: tomek Differential Revision: https://phab.comm.dev/D14063 --- native/profile/profile-screen.react.js | 27 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/native/profile/profile-screen.react.js b/native/profile/profile-screen.react.js index d2d798a65d..f7a426c3cd 100644 --- a/native/profile/profile-screen.react.js +++ b/native/profile/profile-screen.react.js @@ -12,8 +12,8 @@ import { useSecondaryDeviceLogOut, } from 'lib/actions/user-actions.js'; import { useStringForUser } from 'lib/hooks/ens-cache.js'; +import { useCheckIfPrimaryDevice } from 'lib/hooks/primary-device-hooks.js'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; -import { getOwnPrimaryDeviceID } from 'lib/selectors/user-selectors.js'; import { accountHasPassword } from 'lib/shared/account-utils.js'; import { type OutboundDMOperationSpecification, @@ -24,7 +24,6 @@ import type { LogOutResult } from 'lib/types/account-types.js'; import type { DMCreateThreadOperation } from 'lib/types/dm-ops'; import { thickThreadTypes } from 'lib/types/thread-types-enum.js'; import { type CurrentUserInfo } from 'lib/types/user-types.js'; -import { getContentSigningKey } from 'lib/utils/crypto-utils.js'; import { useCurrentUserFID } from 'lib/utils/farcaster-utils.js'; import { useDispatchActionPromise, @@ -168,7 +167,7 @@ type BaseProps = { type Props = { ...BaseProps, +currentUserInfo: ?CurrentUserInfo, - +primaryDeviceID: ?string, + +isPrimaryDevice: boolean, +logOutLoading: boolean, +colors: Colors, +styles: $ReadOnly, @@ -233,7 +232,10 @@ class ProfileScreen extends React.PureComponent { } let passwordEditionUI; - if (accountHasPassword(this.props.currentUserInfo)) { + if ( + accountHasPassword(this.props.currentUserInfo) && + this.props.isPrimaryDevice + ) { passwordEditionUI = ( Password @@ -412,12 +414,9 @@ class ProfileScreen extends React.PureComponent { if (this.loggedOutOrLoggingOut) { return; } - const { primaryDeviceID } = this.props; - const currentDeviceID = await getContentSigningKey(); - const isPrimaryDevice = currentDeviceID === primaryDeviceID; let alertTitle, alertMessage, onPressAction; - if (isPrimaryDevice) { + if (this.props.isPrimaryDevice) { alertTitle = 'Log out all devices?'; alertMessage = 'This device is your primary device, ' + @@ -560,7 +559,6 @@ const logOutLoadingStatusSelector = const ConnectedProfileScreen: React.ComponentType = React.memo(function ConnectedProfileScreen(props: BaseProps) { const currentUserInfo = useSelector(state => state.currentUserInfo); - const primaryDeviceID = useSelector(getOwnPrimaryDeviceID); const logOutLoading = useSelector(logOutLoadingStatusSelector) === 'loading'; const colors = useColors(); @@ -574,6 +572,8 @@ const ConnectedProfileScreen: React.ComponentType = accountHasPassword(state.currentUserInfo), ); const currentUserID = useCurrentUserFID(); + const [isPrimaryDevice, setIsPrimaryDevice] = React.useState(false); + const checkIfPrimaryDevice = useCheckIfPrimaryDevice(); const showVersionUnsupportedAlert = useShowVersionUnsupportedAlert(false); const callLogOut = useLogOut({ @@ -607,11 +607,18 @@ const ConnectedProfileScreen: React.ComponentType = await processAndSendDMOperation(specification); }, [processAndSendDMOperation, userID]); + React.useEffect(() => { + void (async () => { + const checkIfPrimaryDeviceResult = await checkIfPrimaryDevice(); + setIsPrimaryDevice(checkIfPrimaryDeviceResult); + })(); + }, [checkIfPrimaryDevice]); + return (