Page MenuHomePhabricator

D10202.id34696.diff
No OneTemporary

D10202.id34696.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
@@ -1,5 +1,8 @@
// @flow
+import * as React from 'react';
+
+import { preRequestUserStateSelector } from '../selectors/account-selectors.js';
import threadWatcher from '../shared/thread-watcher.js';
import type {
LogOutResult,
@@ -18,6 +21,7 @@
UpdateUserAvatarResponse,
} from '../types/avatar-types.js';
import type { RawEntryInfo, CalendarQuery } from '../types/entry-types.js';
+import type { IdentityServiceClient } from '../types/identity-service-types';
import type {
RawMessageInfo,
MessageTruncationStatuses,
@@ -56,6 +60,7 @@
import { getConfig } from '../utils/config.js';
import type { CallKeyserverEndpoint } from '../utils/keyserver-call';
import { useKeyserverCall } from '../utils/keyserver-call.js';
+import { useSelector } from '../utils/redux-utils.js';
import sleep from '../utils/sleep.js';
import { ashoatKeyserverID } from '../utils/validation-utils.js';
@@ -149,6 +154,31 @@
return useKeyserverCall(deleteKeyserverAccount);
}
+const deleteIdentityAccountActionTypes = Object.freeze({
+ started: 'DELETE_IDENTITY_ACCOUNT_STARTED',
+ success: 'DELETE_IDENTITY_ACCOUNT_SUCCESS',
+ failed: 'DELETE_IDENTITY_ACCOUNT_FAILED',
+});
+
+function useDeleteIdentityAccount(
+ client: IdentityServiceClient,
+ deviceID: ?string,
+): () => Promise<LogOutResult> {
+ const preRequestUserState = useSelector(preRequestUserStateSelector);
+ const userID = useSelector(state => state.currentUserInfo?.id);
+ const accessToken = useSelector(state => state.commServicesAccessToken);
+
+ const deleteIdentityAccount = React.useCallback(async () => {
+ if (!userID || !accessToken || !deviceID) {
+ throw new Error('missing identity service auth metadata');
+ }
+ await client.deleteUser(userID, deviceID, accessToken);
+ return { currentUserInfo: loggedOutUserInfo, preRequestUserState };
+ }, [client, userID, deviceID, accessToken, preRequestUserState]);
+
+ return deleteIdentityAccount;
+}
+
const registerActionTypes = Object.freeze({
started: 'REGISTER_STARTED',
success: 'REGISTER_SUCCESS',
@@ -526,4 +556,6 @@
updateUserAvatar,
resetUserStateActionType,
setAccessTokenActionType,
+ deleteIdentityAccountActionTypes,
+ useDeleteIdentityAccount,
};
diff --git a/lib/types/identity-service-types.js b/lib/types/identity-service-types.js
--- a/lib/types/identity-service-types.js
+++ b/lib/types/identity-service-types.js
@@ -19,6 +19,14 @@
+oneTimeNotifPrekey: ?string,
};
+export interface IdentityServiceClient {
+ +deleteUser: (
+ userID: string,
+ deviceID: string,
+ accessToken: string,
+ ) => Promise<void>;
+}
+
export type IdentityServiceAuthLayer = {
+userID: string,
+deviceID: string,
diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js
--- a/lib/types/redux-types.js
+++ b/lib/types/redux-types.js
@@ -229,6 +229,22 @@
+payload: LogOutResult,
+loadingInfo: LoadingInfo,
}
+ | {
+ +type: 'DELETE_IDENTITY_ACCOUNT_STARTED',
+ +payload?: void,
+ +loadingInfo: LoadingInfo,
+ }
+ | {
+ +type: 'DELETE_IDENTITY_ACCOUNT_FAILED',
+ +error: true,
+ +payload: Error,
+ +loadingInfo: LoadingInfo,
+ }
+ | {
+ +type: 'DELETE_IDENTITY_ACCOUNT_SUCCESS',
+ +payload: LogOutResult,
+ +loadingInfo: LoadingInfo,
+ }
| {
+type: 'CREATE_LOCAL_ENTRY',
+payload: RawEntryInfo,
diff --git a/native/profile/delete-account.react.js b/native/profile/delete-account.react.js
--- a/native/profile/delete-account.react.js
+++ b/native/profile/delete-account.react.js
@@ -5,20 +5,25 @@
import { ScrollView } from 'react-native-gesture-handler';
import {
+ deleteIdentityAccountActionTypes,
deleteKeyserverAccountActionTypes,
+ useDeleteIdentityAccount,
useDeleteKeyserverAccount,
} from 'lib/actions/user-actions.js';
import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import { useDispatchActionPromise } from 'lib/utils/action-utils.js';
+import { usingCommServicesAccessToken } from 'lib/utils/services-utils.js';
import type { ProfileNavigationProp } from './profile.react.js';
import { deleteNativeCredentialsFor } from '../account/native-credentials.js';
import Button from '../components/button.react.js';
+import { commRustModule } from '../native-modules.js';
import type { NavigationRoute } from '../navigation/route-names.js';
import { useSelector } from '../redux/redux-utils.js';
import { useStyles } from '../themes/colors.js';
import Alert from '../utils/alert.js';
+import { getContentSigningKey } from '../utils/crypto-utils.js';
const loadingStatusSelector = createLoadingStatusSelector(
deleteKeyserverAccountActionTypes,
@@ -30,12 +35,24 @@
};
const DeleteAccount: React.ComponentType<Props> = React.memo<Props>(
function DeleteAccount() {
+ const [deviceID, setDeviceID] = React.useState<?string>();
const loadingStatus = useSelector(loadingStatusSelector);
const preRequestUserState = useSelector(preRequestUserStateSelector);
+
+ React.useEffect(() => {
+ void (async () => {
+ const contentSigningKey = await getContentSigningKey();
+ setDeviceID(contentSigningKey);
+ })();
+ }, []);
const styles = useStyles(unboundStyles);
const dispatchActionPromise = useDispatchActionPromise();
- const callDeleteAccount = useDeleteKeyserverAccount();
+ const callDeleteKeyserverAccount = useDeleteKeyserverAccount();
+ const callDeleteIdentityAccount = useDeleteIdentityAccount(
+ commRustModule,
+ deviceID,
+ );
const buttonContent =
loadingStatus === 'loading' ? (
@@ -49,24 +66,41 @@
[styles.warningText, styles.lastWarningText],
);
- const deleteAction = React.useCallback(async () => {
+ const deleteKeyserverAction = React.useCallback(async () => {
try {
await deleteNativeCredentialsFor();
- return await callDeleteAccount(preRequestUserState);
+ return await callDeleteKeyserverAccount(preRequestUserState);
} catch (e) {
Alert.alert('Unknown error', 'Uhh... try again?', [{ text: 'OK' }], {
cancelable: false,
});
throw e;
}
- }, [callDeleteAccount, preRequestUserState]);
+ }, [callDeleteKeyserverAccount, preRequestUserState]);
+
+ const deleteIdentityAction = React.useCallback(async () => {
+ try {
+ return await callDeleteIdentityAccount();
+ } catch (e) {
+ Alert.alert('Unknown error', 'Uhh... try again?', [{ text: 'OK' }], {
+ cancelable: false,
+ });
+ throw e;
+ }
+ }, [callDeleteIdentityAccount]);
const onDelete = React.useCallback(() => {
void dispatchActionPromise(
deleteKeyserverAccountActionTypes,
- deleteAction(),
+ deleteKeyserverAction(),
);
- }, [dispatchActionPromise, deleteAction]);
+ if (usingCommServicesAccessToken) {
+ void dispatchActionPromise(
+ deleteIdentityAccountActionTypes,
+ deleteIdentityAction(),
+ );
+ }
+ }, [dispatchActionPromise, deleteKeyserverAction, deleteIdentityAction]);
return (
<ScrollView

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 7, 12:14 AM (21 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2251523
Default Alt Text
D10202.id34696.diff (7 KB)

Event Timeline