remove userService related code

This commit is contained in:
Abhinav 2023-11-02 21:21:48 +05:30
parent 9cfbc96fc7
commit 87ae9f8d31
12 changed files with 25 additions and 413 deletions

View file

@ -14,6 +14,7 @@
},
"dependencies": {
"@ente/accounts": "*",
"@ente/shared": "*",
"@date-io/date-fns": "^2.14.0",
"@emotion/cache": "^11.10.5",
"@emotion/react": "^11.10.6",

View file

@ -2,11 +2,7 @@ import { Button, Link, Stack } from '@mui/material';
import { AppContext } from 'pages/_app';
import { useContext, useEffect, useRef, useState } from 'react';
import { preloadImage, initiateEmail } from 'utils/common';
import {
deleteAccount,
getAccountDeleteChallenge,
logoutUser,
} from 'services/userService';
import { deleteAccount, getAccountDeleteChallenge } from 'services/userService';
import { logError } from 'utils/sentry';
import { decryptDeleteAccountChallenge } from 'utils/crypto';
import { Trans } from 'react-i18next';
@ -20,6 +16,7 @@ import MultilineInput from './MultilineInput';
import { CheckboxInput } from './CheckboxInput';
import EnteButton from './EnteButton';
import { GalleryContext } from 'pages/gallery';
import { logoutUser } from '@ente/accounts/services/user';
interface Iprops {
onClose: () => void;

View file

@ -1,7 +1,7 @@
import React, { useContext, useState } from 'react';
import { t } from 'i18next';
import { logoutUser } from 'services/userService';
import { logoutUser } from '@ente/accounts/services/user';
import { AppContext } from 'pages/_app';
import DeleteAccountModal from 'components/DeleteAccountModal';
import { EnteMenuItem } from 'components/Menu/EnteMenuItem';

View file

@ -2,7 +2,7 @@ import { HorizontalFlex } from 'components/Container';
import NavbarBase from 'components/Navbar/base';
import React from 'react';
import { t } from 'i18next';
import { logoutUser } from 'services/userService';
import { logoutUser } from '@ente/accounts/services/user';
import { EnteLogo } from 'components/EnteLogo';
import OverflowMenu from 'components/OverflowMenu/menu';
import { OverflowMenuOption } from 'components/OverflowMenu/option';

View file

@ -47,7 +47,7 @@ import FullScreenDropZone from 'components/FullScreenDropZone';
import useFileInput from 'hooks/useFileInput';
import { useDropzone } from 'react-dropzone';
import UploadSelectorInputs from 'components/UploadSelectorInputs';
import { logoutUser } from 'services/userService';
import { logoutUser } from '@ente/accounts/services/user';
import UploadButton from 'components/Upload/UploadButton';
import bs58 from 'bs58';
import AddPhotoAlternateOutlined from '@mui/icons-material/AddPhotoAlternateOutlined';

View file

@ -1,70 +1,31 @@
import { PAGES } from 'constants/pages';
import {
getEndpoint,
getFamilyPortalURL,
isDevDeployment,
} from 'utils/common/apiUtil';
import { clearKeys } from 'utils/storage/sessionStorage';
import router from 'next/router';
import { clearData, getData, LS_KEYS } from 'utils/storage/localStorage';
import { getData, LS_KEYS } from '@ente/shared/storage/localStorage';
import localForage from 'utils/storage/localForage';
import { getToken } from 'utils/common/key';
import HTTPService from './HTTPService';
import {
computeVerifierHelper,
generateLoginSubKey,
generateSRPClient,
getRecoveryKey,
} from 'utils/crypto';
import { getRecoveryKey } from 'utils/crypto';
import { logError } from 'utils/sentry';
import { eventBus, Events } from './events';
import {
KeyAttributes,
RecoveryKey,
TwoFactorSecret,
TwoFactorVerificationResponse,
TwoFactorRecoveryResponse,
UserDetails,
DeleteChallengeResponse,
GetRemoteStoreValueResponse,
SetupSRPRequest,
CreateSRPSessionResponse,
UserVerificationResponse,
GetFeatureFlagResponse,
SetupSRPResponse,
CompleteSRPSetupRequest,
CompleteSRPSetupResponse,
SRPSetupAttributes,
SRPAttributes,
UpdateSRPAndKeysRequest,
UpdateSRPAndKeysResponse,
GetSRPAttributesResponse,
} from 'types/user';
import { ApiError, CustomError } from 'utils/error';
import isElectron from 'is-electron';
import safeStorageService from './electron/safeStorage';
import { deleteAllCache } from 'utils/storage/cache';
import { B64EncryptionResult } from 'types/crypto';
import { ApiError } from 'utils/error';
import { getLocalFamilyData, isPartOfFamily } from 'utils/user/family';
import { AxiosResponse, HttpStatusCode } from 'axios';
import { APPS, getAppName } from 'constants/apps';
import { addLocalLog } from 'utils/logging';
import { convertBase64ToBuffer, convertBufferToBase64 } from 'utils/user';
import { setLocalMapEnabled } from 'utils/storage';
import InMemoryStore, { MS_KEYS } from './InMemoryStore';
import { putAttributes } from '@ente/accounts/api/user';
import { logoutUser } from '@ente/accounts/services/user';
const ENDPOINT = getEndpoint();
const HAS_SET_KEYS = 'hasSetKeys';
export const sendOtt = (email: string) => {
const appName = getAppName();
return HTTPService.post(`${ENDPOINT}/users/ott`, {
email,
client: appName === APPS.AUTH ? 'totp' : 'web',
});
};
export const getPublicKey = async (email: string) => {
const token = getToken();
@ -127,70 +88,6 @@ export const getRoadmapRedirectURL = async () => {
}
};
export const verifyOtt = (email: string, ott: string) =>
HTTPService.post(`${ENDPOINT}/users/verify-email`, { email, ott });
export const putAttributes = (token: string, keyAttributes: KeyAttributes) =>
HTTPService.put(`${ENDPOINT}/users/attributes`, { keyAttributes }, null, {
'X-Auth-Token': token,
});
export const setRecoveryKey = (token: string, recoveryKey: RecoveryKey) =>
HTTPService.put(`${ENDPOINT}/users/recovery-key`, recoveryKey, null, {
'X-Auth-Token': token,
});
export const logoutUser = async () => {
try {
try {
// ignore server logout result as logoutUser can be triggered before sign up or on token expiry
await _logout();
} catch (e) {
//ignore
}
try {
InMemoryStore.clear();
} catch (e) {
logError(e, 'clear InMemoryStore failed');
}
try {
clearKeys();
} catch (e) {
logError(e, 'clearKeys failed');
}
try {
clearData();
} catch (e) {
logError(e, 'clearData failed');
}
try {
await deleteAllCache();
} catch (e) {
logError(e, 'deleteAllCache failed');
}
try {
await clearFiles();
} catch (e) {
logError(e, 'clearFiles failed');
}
if (isElectron()) {
try {
safeStorageService.clearElectronStore();
} catch (e) {
logError(e, 'clearElectronStore failed');
}
}
try {
eventBus.emit(Events.LOGOUT);
} catch (e) {
logError(e, 'Error in logout handlers');
}
router.push(PAGES.ROOT);
} catch (e) {
logError(e, 'logoutUser failed');
}
};
export const clearFiles = async () => {
await localForage.clear();
};
@ -211,7 +108,6 @@ export const isTokenValid = async (token: string) => {
if (!resp.data['hasSetKeys']) {
try {
await putAttributes(
token,
getData(LS_KEYS.ORIGINAL_KEY_ATTRIBUTES)
);
} catch (e) {
@ -235,71 +131,6 @@ export const isTokenValid = async (token: string) => {
}
};
export const setupTwoFactor = async () => {
const resp = await HTTPService.post(
`${ENDPOINT}/users/two-factor/setup`,
null,
null,
{
'X-Auth-Token': getToken(),
}
);
return resp.data as TwoFactorSecret;
};
export const enableTwoFactor = async (
code: string,
recoveryEncryptedTwoFactorSecret: B64EncryptionResult
) => {
await HTTPService.post(
`${ENDPOINT}/users/two-factor/enable`,
{
code,
encryptedTwoFactorSecret:
recoveryEncryptedTwoFactorSecret.encryptedData,
twoFactorSecretDecryptionNonce:
recoveryEncryptedTwoFactorSecret.nonce,
},
null,
{
'X-Auth-Token': getToken(),
}
);
};
export const verifyTwoFactor = async (code: string, sessionID: string) => {
const resp = await HTTPService.post(
`${ENDPOINT}/users/two-factor/verify`,
{
code,
sessionID,
},
null
);
return resp.data as TwoFactorVerificationResponse;
};
export const recoverTwoFactor = async (sessionID: string) => {
const resp = await HTTPService.get(`${ENDPOINT}/users/two-factor/recover`, {
sessionID,
});
return resp.data as TwoFactorRecoveryResponse;
};
export const removeTwoFactor = async (sessionID: string, secret: string) => {
const resp = await HTTPService.post(`${ENDPOINT}/users/two-factor/remove`, {
sessionID,
secret,
});
return resp.data as TwoFactorVerificationResponse;
};
export const disableTwoFactor = async () => {
await HTTPService.post(`${ENDPOINT}/users/two-factor/disable`, null, null, {
'X-Auth-Token': getToken(),
});
};
export const getTwoFactorStatus = async () => {
const resp = await HTTPService.get(
`${ENDPOINT}/users/two-factor/status`,
@ -547,211 +378,3 @@ export async function getDisableCFUploadProxyFlag(): Promise<boolean> {
return false;
}
}
export const getSRPAttributes = async (
email: string
): Promise<SRPAttributes | null> => {
try {
const resp = await HTTPService.get(`${ENDPOINT}/users/srp/attributes`, {
email,
});
return (resp.data as GetSRPAttributesResponse).attributes;
} catch (e) {
logError(e, 'failed to get SRP attributes');
return null;
}
};
export const configureSRP = async ({
srpSalt,
srpUserID,
srpVerifier,
loginSubKey,
}: SRPSetupAttributes) => {
try {
const srpConfigureInProgress = InMemoryStore.get(
MS_KEYS.SRP_CONFIGURE_IN_PROGRESS
);
if (srpConfigureInProgress) {
throw Error('SRP configure already in progress');
}
InMemoryStore.set(MS_KEYS.SRP_CONFIGURE_IN_PROGRESS, true);
const srpClient = await generateSRPClient(
srpSalt,
srpUserID,
loginSubKey
);
const srpA = convertBufferToBase64(srpClient.computeA());
addLocalLog(() => `srp a: ${srpA}`);
const token = getToken();
const { setupID, srpB } = await startSRPSetup(token, {
srpA,
srpUserID,
srpSalt,
srpVerifier,
});
srpClient.setB(convertBase64ToBuffer(srpB));
const srpM1 = convertBufferToBase64(srpClient.computeM1());
const { srpM2 } = await completeSRPSetup(token, {
srpM1,
setupID,
});
srpClient.checkM2(convertBase64ToBuffer(srpM2));
} catch (e) {
logError(e, 'srp configure failed');
throw e;
} finally {
InMemoryStore.set(MS_KEYS.SRP_CONFIGURE_IN_PROGRESS, false);
}
};
export const startSRPSetup = async (
token: string,
setupSRPRequest: SetupSRPRequest
): Promise<SetupSRPResponse> => {
try {
const resp = await HTTPService.post(
`${ENDPOINT}/users/srp/setup`,
setupSRPRequest,
null,
{
'X-Auth-Token': token,
}
);
return resp.data as SetupSRPResponse;
} catch (e) {
logError(e, 'failed to post SRP attributes');
throw e;
}
};
export const completeSRPSetup = async (
token: string,
completeSRPSetupRequest: CompleteSRPSetupRequest
) => {
try {
const resp = await HTTPService.post(
`${ENDPOINT}/users/srp/complete`,
completeSRPSetupRequest,
null,
{
'X-Auth-Token': token,
}
);
return resp.data as CompleteSRPSetupResponse;
} catch (e) {
logError(e, 'failed to complete SRP setup');
throw e;
}
};
export const loginViaSRP = async (
srpAttributes: SRPAttributes,
kek: string
): Promise<UserVerificationResponse> => {
try {
const loginSubKey = await generateLoginSubKey(kek);
const srpClient = await generateSRPClient(
srpAttributes.srpSalt,
srpAttributes.srpUserID,
loginSubKey
);
const srpVerifier = computeVerifierHelper(
srpAttributes.srpSalt,
srpAttributes.srpUserID,
loginSubKey
);
addLocalLog(() => `srp verifier: ${srpVerifier}`);
const srpA = srpClient.computeA();
const { srpB, sessionID } = await createSRPSession(
srpAttributes.srpUserID,
convertBufferToBase64(srpA)
);
srpClient.setB(convertBase64ToBuffer(srpB));
const m1 = srpClient.computeM1();
addLocalLog(() => `srp m1: ${convertBufferToBase64(m1)}`);
const { srpM2, ...rest } = await verifySRPSession(
sessionID,
srpAttributes.srpUserID,
convertBufferToBase64(m1)
);
addLocalLog(() => `srp verify session successful,srpM2: ${srpM2}`);
srpClient.checkM2(convertBase64ToBuffer(srpM2));
addLocalLog(() => `srp server verify successful`);
return rest;
} catch (e) {
logError(e, 'srp verify failed');
throw e;
}
};
export const createSRPSession = async (srpUserID: string, srpA: string) => {
try {
const resp = await HTTPService.post(
`${ENDPOINT}/users/srp/create-session`,
{
srpUserID,
srpA,
}
);
return resp.data as CreateSRPSessionResponse;
} catch (e) {
logError(e, 'createSRPSession failed');
throw e;
}
};
export const verifySRPSession = async (
sessionID: string,
srpUserID: string,
srpM1: string
) => {
try {
const resp = await HTTPService.post(
`${ENDPOINT}/users/srp/verify-session`,
{
sessionID,
srpUserID,
srpM1,
},
null
);
return resp.data as UserVerificationResponse;
} catch (e) {
logError(e, 'verifySRPSession failed');
if (
e instanceof ApiError &&
e.httpStatusCode === HttpStatusCode.Forbidden
) {
throw Error(CustomError.INCORRECT_PASSWORD);
} else {
throw e;
}
}
};
export const updateSRPAndKeys = async (
token: string,
updateSRPAndKeyRequest: UpdateSRPAndKeysRequest
): Promise<UpdateSRPAndKeysResponse> => {
const resp = await HTTPService.post(
`${ENDPOINT}/users/srp/update`,
updateSRPAndKeyRequest,
null,
{
'X-Auth-Token': token,
}
);
return resp.data as UpdateSRPAndKeysResponse;
};

View file

@ -8,7 +8,7 @@ import { AppUpdateInfo } from 'types/electron';
import InfoOutlined from '@mui/icons-material/InfoRounded';
import { Trans } from 'react-i18next';
import { Subscription } from 'types/billing';
import { logoutUser } from 'services/userService';
import { logoutUser } from '@ente/accounts/services/user';
import { Link } from '@mui/material';
import { OPEN_STREET_MAP_LINK } from 'components/Sidebar/EnableMap';
export const getDownloadAppMessage = (): DialogBoxAttributes => {

View file

@ -252,10 +252,6 @@ export default function Credentials({
);
}
const logoutHandler = () => {
logoutUser(router);
};
return (
<VerticallyCentered>
<FormPaper style={{ minWidth: '320px' }}>
@ -273,7 +269,7 @@ export default function Credentials({
<LinkButton onClick={redirectToRecoverPage}>
{t('FORGOT_PASSWORD')}
</LinkButton>
<LinkButton onClick={logoutHandler}>
<LinkButton onClick={logoutUser}>
{t('CHANGE_EMAIL')}
</LinkButton>
</FormPaperFooter>

View file

@ -69,7 +69,7 @@ export default function Recover({ router, appContext }: PageProps) {
e instanceof ApiError &&
e.httpStatusCode === HttpStatusCode.NotFound
) {
logoutUser(router);
logoutUser();
} else {
logError(e, 'two factor recovery page setup failed');
setDoesHaveEncryptedRecoveryKey(false);

View file

@ -59,15 +59,13 @@ export default function TwoFactorVerify({ router }: PageProps) {
e instanceof ApiError &&
e.httpStatusCode === HttpStatusCode.NotFound
) {
logoutUser(router);
logoutUser();
} else {
throw e;
}
}
};
const logoutHandler = () => logoutUser(router);
return (
<VerticallyCentered>
<FormPaper sx={{ maxWidth: '410px' }}>
@ -79,7 +77,7 @@ export default function TwoFactorVerify({ router }: PageProps) {
onClick={() => router.push(PAGES.TWO_FACTOR_RECOVER)}>
{t('LOST_DEVICE')}
</LinkButton>
<LinkButton onClick={logoutHandler}>
<LinkButton onClick={logoutUser}>
{t('CHANGE_EMAIL')}
</LinkButton>
</FormPaperFooter>

View file

@ -140,10 +140,6 @@ export default function VerifyPage({ appContext, router, appName }: PageProps) {
);
}
const logoutHandler = async () => {
logoutUser(router);
};
return (
<VerticallyCentered>
<FormPaper>
@ -175,7 +171,7 @@ export default function VerifyPage({ appContext, router, appName }: PageProps) {
)}
{resend === 1 && <span>{t('SENDING')}</span>}
{resend === 2 && <span>{t('SENT')}</span>}
<LinkButton onClick={logoutHandler}>
<LinkButton onClick={logoutUser}>
{t('CHANGE_EMAIL')}
</LinkButton>
</FormPaperFooter>

View file

@ -1,12 +1,13 @@
import InMemoryStore from '@ente/shared/storage/InMemoryStore';
import { _logout } from '../api/user';
import { PAGES } from '../constants/pages';
import { NextRouter } from 'next/router';
import { clearKeys } from '@ente/shared/storage/sessionStorage';
import { clearData } from '@ente/shared/storage/localStorage';
import { logError } from '@ente/shared/sentry';
import { clearFiles } from '@ente/shared/storage/localForage/helpers';
import router from 'next/router';
export const logoutUser = async (router: NextRouter) => {
export const logoutUser = async () => {
try {
try {
await _logout();
@ -35,11 +36,11 @@ export const logoutUser = async (router: NextRouter) => {
// } catch (e) {
// logError(e, 'deleteAllCache failed');
// }
// try {
// await clearFiles();
// } catch (e) {
// logError(e, 'clearFiles failed');
// }
try {
await clearFiles();
} catch (e) {
logError(e, 'clearFiles failed');
}
// if (isElectron()) {
// try {
// safeStorageService.clearElectronStore();