ソースを参照

[Cast] Use common shared packages

Neeraj Gupta 1 年間 前
コミット
1e583414d3

+ 4 - 52
apps/cast/sentry.client.config.js

@@ -1,53 +1,5 @@
-import * as Sentry from '@sentry/nextjs';
-import { getSentryUserID } from 'utils/user';
-import { getHasOptedOutOfCrashReports } from 'utils/storage/index';
-import { runningInBrowser } from '@ente/shared/apps/browser';
-import { getSentryTunnelURL } from '@ente/shared/network/api';
-import {
-    getSentryDSN,
-    getSentryENV,
-    getSentryRelease,
-    getIsSentryEnabled,
-} from 'constants/sentry';
+import { setupSentry } from '@ente/shared/sentry/config/sentry.config.base';
 
-const HAS_OPTED_OUT_OF_CRASH_REPORTING =
-    runningInBrowser() && getHasOptedOutOfCrashReports();
-
-if (!HAS_OPTED_OUT_OF_CRASH_REPORTING) {
-    const SENTRY_DSN = getSentryDSN();
-    const SENTRY_ENV = getSentryENV();
-    const SENTRY_RELEASE = getSentryRelease();
-    const IS_ENABLED = getIsSentryEnabled();
-
-    Sentry.init({
-        dsn: SENTRY_DSN,
-        enabled: IS_ENABLED,
-        environment: SENTRY_ENV,
-        release: SENTRY_RELEASE,
-        attachStacktrace: true,
-        autoSessionTracking: false,
-        tunnel: getSentryTunnelURL(),
-        beforeSend(event) {
-            event.request = event.request || {};
-            const currentURL = new URL(document.location.href);
-            currentURL.hash = '';
-            event.request.url = currentURL;
-            return event;
-        },
-        integrations: function (i) {
-            return i.filter(function (i) {
-                return i.name !== 'Breadcrumbs';
-            });
-        },
-        // ...
-        // Note: if you want to override the automatic release value, do not set a
-        // `release` value here - use the environment variable `SENTRY_RELEASE`, so
-        // that it will also get attached to your source maps
-    });
-
-    const main = async () => {
-        Sentry.setUser({ id: await getSentryUserID() });
-    };
-
-    main();
-}
+const DEFAULT_SENTRY_DSN =
+    'https://bd3656fc40d74d5e8f278132817963a3@sentry.ente.io/2';
+setupSentry(DEFAULT_SENTRY_DSN);

+ 0 - 28
apps/cast/sentry.server.config.js

@@ -1,28 +0,0 @@
-import * as Sentry from '@sentry/nextjs';
-import {
-    getSentryDSN,
-    getSentryENV,
-    getSentryRelease,
-    getIsSentryEnabled,
-} from 'constants/sentry';
-
-import { getSentryUserID } from 'utils/user';
-
-const SENTRY_DSN = getSentryDSN();
-const SENTRY_ENV = getSentryENV();
-const SENTRY_RELEASE = getSentryRelease();
-const IS_ENABLED = getIsSentryEnabled();
-
-Sentry.init({
-    dsn: SENTRY_DSN,
-    enabled: IS_ENABLED,
-    environment: SENTRY_ENV,
-    release: SENTRY_RELEASE,
-    autoSessionTracking: false,
-});
-
-const main = async () => {
-    Sentry.setUser({ id: await getSentryUserID() });
-};
-
-main();

+ 9 - 2
apps/cast/src/pages/slideshow.tsx

@@ -7,6 +7,7 @@ import { getCollectionWithKey } from 'services/collectionService';
 import { syncFiles } from 'services/fileService';
 import { EnteFile } from 'types/file';
 import { downloadFileAsBlob, isRawFileFromFileName } from 'utils/file';
+import { logError } from 'utils/sentry';
 
 export const SlideshowContext = createContext<{
     showNextSlide: () => void;
@@ -36,9 +37,13 @@ export default function Slideshow() {
                 'targetCollectionKey'
             );
 
+            const castToken = window.localStorage.getItem('token');
+
             const collection = await getCollectionWithKey(
                 Number(requestedCollectionID),
-                requestedCollectionKey
+                requestedCollectionKey,
+                'cast',
+                castToken
             );
 
             const files = await syncFiles('normal', [collection], () => {});
@@ -48,7 +53,9 @@ export default function Slideshow() {
                     files.filter((file) => isFileEligibleForCast(file))
                 );
             }
-        } catch {
+        } catch (e) {
+            logError(e, 'error during sync');
+            alert('error, redirect to home' + e);
             router.push('/');
         }
     };

+ 0 - 241
apps/cast/src/services/HTTPService.ts

@@ -1,241 +0,0 @@
-import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
-import { addLogLine } from 'utils/logging';
-import { logError } from 'utils/sentry';
-import { ApiError, CustomError, isApiErrorResponse } from 'utils/error';
-
-interface IHTTPHeaders {
-    [headerKey: string]: any;
-}
-
-interface IQueryPrams {
-    [paramName: string]: any;
-}
-
-/**
- * Service to manage all HTTP calls.
- */
-class HTTPService {
-    constructor() {
-        axios.interceptors.response.use(
-            (response) => Promise.resolve(response),
-            (error) => {
-                const config = error.config as AxiosRequestConfig;
-                if (error.response) {
-                    const response = error.response as AxiosResponse;
-                    let apiError: ApiError;
-                    // The request was made and the server responded with a status code
-                    // that falls out of the range of 2xx
-                    if (isApiErrorResponse(response.data)) {
-                        const responseData = response.data;
-                        logError(error, 'HTTP Service Error', {
-                            url: config.url,
-                            method: config.method,
-                            xRequestId: response.headers['x-request-id'],
-                            httpStatus: response.status,
-                            errMessage: responseData.message,
-                            errCode: responseData.code,
-                        });
-                        apiError = new ApiError(
-                            responseData.message,
-                            responseData.code,
-                            response.status
-                        );
-                    } else {
-                        if (response.status >= 400 && response.status < 500) {
-                            apiError = new ApiError(
-                                CustomError.CLIENT_ERROR,
-                                '',
-                                response.status
-                            );
-                        } else {
-                            apiError = new ApiError(
-                                CustomError.ServerError,
-                                '',
-                                response.status
-                            );
-                        }
-                    }
-                    logError(apiError, 'HTTP Service Error', {
-                        url: config.url,
-                        method: config.method,
-                        cfRay: response.headers['cf-ray'],
-                        xRequestId: response.headers['x-request-id'],
-                        httpStatus: response.status,
-                    });
-                    throw apiError;
-                } else if (error.request) {
-                    // The request was made but no response was received
-                    // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
-                    // http.ClientRequest in node.js
-                    addLogLine(
-                        'request failed- no response',
-                        `url: ${config.url}`,
-                        `method: ${config.method}`
-                    );
-                    return Promise.reject(error);
-                } else {
-                    // Something happened in setting up the request that triggered an Error
-                    addLogLine(
-                        'request failed- axios error',
-                        `url: ${config.url}`,
-                        `method: ${config.method}`
-                    );
-                    return Promise.reject(error);
-                }
-            }
-        );
-    }
-
-    /**
-     * header object to be append to all api calls.
-     */
-    private headers: IHTTPHeaders = {
-        'content-type': 'application/json',
-    };
-
-    /**
-     * Sets the headers to the given object.
-     */
-    public setHeaders(headers: IHTTPHeaders) {
-        this.headers = {
-            ...this.headers,
-            ...headers,
-        };
-    }
-
-    /**
-     * Adds a header to list of headers.
-     */
-    public appendHeader(key: string, value: string) {
-        this.headers = {
-            ...this.headers,
-            [key]: value,
-        };
-    }
-
-    /**
-     * Removes the given header.
-     */
-    public removeHeader(key: string) {
-        this.headers[key] = undefined;
-    }
-
-    /**
-     * Returns axios interceptors.
-     */
-    // eslint-disable-next-line class-methods-use-this
-    public getInterceptors() {
-        return axios.interceptors;
-    }
-
-    /**
-     * Generic HTTP request.
-     * This is done so that developer can use any functionality
-     * provided by axios. Here, only the set headers are spread
-     * over what was sent in config.
-     */
-    public async request(config: AxiosRequestConfig, customConfig?: any) {
-        // eslint-disable-next-line no-param-reassign
-        config.headers = {
-            ...this.headers,
-            ...config.headers,
-        };
-        if (customConfig?.cancel) {
-            config.cancelToken = new axios.CancelToken(
-                (c) => (customConfig.cancel.exec = c)
-            );
-        }
-        return await axios({ ...config, ...customConfig });
-    }
-
-    /**
-     * Get request.
-     */
-    public get(
-        url: string,
-        params?: IQueryPrams,
-        headers?: IHTTPHeaders,
-        customConfig?: any
-    ) {
-        return this.request(
-            {
-                headers,
-                method: 'GET',
-                params,
-                url,
-            },
-            customConfig
-        );
-    }
-
-    /**
-     * Post request
-     */
-    public post(
-        url: string,
-        data?: any,
-        params?: IQueryPrams,
-        headers?: IHTTPHeaders,
-        customConfig?: any
-    ) {
-        return this.request(
-            {
-                data,
-                headers,
-                method: 'POST',
-                params,
-                url,
-            },
-            customConfig
-        );
-    }
-
-    /**
-     * Put request
-     */
-    public put(
-        url: string,
-        data: any,
-        params?: IQueryPrams,
-        headers?: IHTTPHeaders,
-        customConfig?: any
-    ) {
-        return this.request(
-            {
-                data,
-                headers,
-                method: 'PUT',
-                params,
-                url,
-            },
-            customConfig
-        );
-    }
-
-    /**
-     * Delete request
-     */
-    public delete(
-        url: string,
-        data: any,
-        params?: IQueryPrams,
-        headers?: IHTTPHeaders,
-        customConfig?: any
-    ) {
-        return this.request(
-            {
-                data,
-                headers,
-                method: 'DELETE',
-                params,
-                url,
-            },
-            customConfig
-        );
-    }
-}
-
-// Creates a Singleton Service.
-// This will help me maintain common headers / functionality
-// at a central place.
-export default new HTTPService();

+ 13 - 40
apps/cast/src/services/collectionService.ts

@@ -1,11 +1,6 @@
-import { getData, LS_KEYS } from 'utils/storage/localStorage';
-import localForage from 'utils/storage/localForage';
 import { getActualKey } from '@ente/shared/user';
 import { batch } from '@ente/shared/batch';
-import { getPublicKey } from './userService';
-import HTTPService from './HTTPService';
 import { EnteFile } from 'types/file';
-import { logError } from 'utils/sentry';
 import { CustomError } from 'utils/error';
 import {
     sortFiles,
@@ -71,6 +66,10 @@ import { EncryptedMagicMetadata } from 'types/magicMetadata';
 import { VISIBILITY_STATE } from 'types/magicMetadata';
 import { getEndpoint } from '@ente/shared/network/api';
 import { getToken } from '@ente/shared/storage/localStorage/helpers';
+import HTTPService from '@ente/shared/network/HTTPService';
+import { logError } from '@ente/shared/sentry';
+import { LS_KEYS, getData } from '@ente/shared/storage/localStorage';
+import localForage from '@ente/shared/storage/localForage';
 
 const ENDPOINT = getEndpoint();
 const COLLECTION_TABLE = 'collections';
@@ -347,10 +346,17 @@ export const getCollection = async (
 
 export const getCollectionWithKey = async (
     collectionID: number,
-    key: string
+    key: string,
+    tokenType: 'user' | 'cast' = 'user',
+    castToken?: string
 ): Promise<Collection> => {
     try {
-        const token = getToken();
+        let token;
+        if (tokenType === 'user') {
+            token = getToken();
+        } else {
+            token = castToken!;
+        }
         if (!token) {
             return;
         }
@@ -974,39 +980,6 @@ export const renameCollection = async (
     );
 };
 
-export const shareCollection = async (
-    collection: Collection,
-    withUserEmail: string,
-    role: string
-) => {
-    try {
-        const cryptoWorker = await ComlinkCryptoWorker.getInstance();
-        const token = getToken();
-        const publicKey: string = await getPublicKey(withUserEmail);
-        const encryptedKey = await cryptoWorker.boxSeal(
-            collection.key,
-            publicKey
-        );
-        const shareCollectionRequest = {
-            collectionID: collection.id,
-            email: withUserEmail,
-            role: role,
-            encryptedKey,
-        };
-        await HTTPService.post(
-            `${ENDPOINT}/collections/share`,
-            shareCollectionRequest,
-            null,
-            {
-                'X-Auth-Token': token,
-            }
-        );
-    } catch (e) {
-        logError(e, 'share collection failed ');
-        throw e;
-    }
-};
-
 export const unshareCollection = async (
     collection: Collection,
     withUserEmail: string

+ 2 - 3
apps/cast/src/services/downloadManager.ts

@@ -3,10 +3,8 @@ import {
     getRenderableFileURL,
     createTypedObjectURL,
 } from 'utils/file';
-import HTTPService from './HTTPService';
 import { EnteFile } from 'types/file';
 
-import { logError } from 'utils/sentry';
 import { FILE_TYPE } from 'constants/file';
 import { CustomError } from 'utils/error';
 import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
@@ -16,9 +14,10 @@ import { Remote } from 'comlink';
 import { DedicatedCryptoWorker } from 'worker/crypto.worker';
 import { LimitedCache } from 'types/cache';
 import { retryAsyncFunction } from 'utils/network';
-import { addLogLine } from 'utils/logging';
 import { getToken } from '@ente/shared/storage/localStorage/helpers';
 import { getFileURL, getThumbnailURL } from '@ente/shared/network/api';
+import HTTPService from '@ente/shared/network/HTTPService';
+import { logError } from '@ente/shared/sentry';
 
 class DownloadManager {
     private fileObjectURLPromise = new Map<

+ 2 - 1
apps/cast/src/services/fileService.ts

@@ -3,7 +3,7 @@ import localForage from 'utils/storage/localForage';
 
 import { getToken } from '@ente/shared/storage/localStorage/helpers';
 import { Collection } from 'types/collection';
-import HTTPService from './HTTPService';
+
 import { logError } from 'utils/sentry';
 import {
     decryptFile,
@@ -29,6 +29,7 @@ import {
 } from './collectionService';
 import { REQUEST_BATCH_SIZE } from 'constants/api';
 import { batch } from '@ente/shared/batch';
+import HTTPService from '@ente/shared/network/HTTPService';
 
 const ENDPOINT = getEndpoint();
 const FILES_TABLE = 'files';

+ 0 - 31
apps/cast/src/services/kexService.ts

@@ -1,31 +0,0 @@
-import { logError } from 'utils/sentry';
-import HTTPService from './HTTPService';
-import { getEndpoint } from '@ente/shared/network/api';
-
-const ENDPOINT = getEndpoint();
-
-export const getKexValue = async (key: string) => {
-    let resp;
-    try {
-        resp = await HTTPService.get(`${ENDPOINT}/kex/get`, {
-            identifier: key,
-        });
-    } catch (e) {
-        logError(e, 'failed to get kex value');
-        throw e;
-    }
-
-    return resp.data.wrappedKey;
-};
-
-export const setKexValue = async (key: string, value: string) => {
-    try {
-        await HTTPService.put(ENDPOINT + '/kex/add', {
-            customIdentifier: key,
-            wrappedKey: value,
-        });
-    } catch (e) {
-        logError(e, 'failed to set kex value');
-        throw e;
-    }
-};

+ 2 - 2
apps/cast/src/services/publicCollectionDownloadManager.ts

@@ -3,10 +3,8 @@ import {
     getRenderableFileURL,
     createTypedObjectURL,
 } from 'utils/file';
-import HTTPService from './HTTPService';
 import { EnteFile } from 'types/file';
 
-import { logError } from 'utils/sentry';
 import { FILE_TYPE } from 'constants/file';
 import { CustomError } from 'utils/error';
 import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
@@ -17,6 +15,8 @@ import {
     getPublicCollectionFileURL,
     getPublicCollectionThumbnailURL,
 } from '@ente/shared/network/api';
+import HTTPService from '@ente/shared/network/HTTPService';
+import { logError } from '@ente/shared/sentry';
 
 class PublicCollectionDownloadManager {
     private fileObjectURLPromise = new Map<

+ 1 - 1
apps/cast/src/services/readerService.ts

@@ -1,6 +1,6 @@
+import { logError } from '@ente/shared/sentry';
 import { ElectronFile } from 'types/upload';
 import { convertBytesToHumanReadable } from 'utils/file/size';
-import { logError } from 'utils/sentry';
 
 export async function getUint8ArrayView(
     file: Blob | ElectronFile

+ 0 - 757
apps/cast/src/services/userService.ts

@@ -1,757 +0,0 @@
-import { PAGES } from 'constants/pages';
-import { clearKeys } from 'utils/storage/sessionStorage';
-import router from 'next/router';
-import { clearData, getData, LS_KEYS } from 'utils/storage/localStorage';
-import localForage from 'utils/storage/localForage';
-import { getToken } from '@ente/shared/storage/localStorage/helpers';
-import HTTPService from './HTTPService';
-import {
-    computeVerifierHelper,
-    generateLoginSubKey,
-    generateSRPClient,
-    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 { 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 {
-    getEndpoint,
-    getFamilyPortalURL,
-    isDevDeployment,
-} from '@ente/shared/network/api';
-
-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();
-
-    const resp = await HTTPService.get(
-        `${ENDPOINT}/users/public-key`,
-        { email },
-        {
-            'X-Auth-Token': token,
-        }
-    );
-    return resp.data.publicKey;
-};
-
-export const getPaymentToken = async () => {
-    const token = getToken();
-
-    const resp = await HTTPService.get(
-        `${ENDPOINT}/users/payment-token`,
-        null,
-        {
-            'X-Auth-Token': token,
-        }
-    );
-    return resp.data['paymentToken'];
-};
-
-export const getFamiliesToken = async () => {
-    try {
-        const token = getToken();
-
-        const resp = await HTTPService.get(
-            `${ENDPOINT}/users/families-token`,
-            null,
-            {
-                'X-Auth-Token': token,
-            }
-        );
-        return resp.data['familiesToken'];
-    } catch (e) {
-        logError(e, 'failed to get family token');
-        throw e;
-    }
-};
-
-export const getRoadmapRedirectURL = async () => {
-    try {
-        const token = getToken();
-
-        const resp = await HTTPService.get(
-            `${ENDPOINT}/users/roadmap/v2`,
-            null,
-            {
-                'X-Auth-Token': token,
-            }
-        );
-        return resp.data['url'];
-    } catch (e) {
-        logError(e, 'failed to get roadmap url');
-        throw e;
-    }
-};
-
-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();
-};
-
-export const isTokenValid = async (token: string) => {
-    try {
-        const resp = await HTTPService.get(
-            `${ENDPOINT}/users/session-validity/v2`,
-            null,
-            {
-                'X-Auth-Token': token,
-            }
-        );
-        try {
-            if (resp.data[HAS_SET_KEYS] === undefined) {
-                throw Error('resp.data.hasSetKey undefined');
-            }
-            if (!resp.data['hasSetKeys']) {
-                try {
-                    await putAttributes(
-                        token,
-                        getData(LS_KEYS.ORIGINAL_KEY_ATTRIBUTES)
-                    );
-                } catch (e) {
-                    logError(e, 'put attribute failed');
-                }
-            }
-        } catch (e) {
-            logError(e, 'hasSetKeys not set in session validity response');
-        }
-        return true;
-    } catch (e) {
-        logError(e, 'session-validity api call failed');
-        if (
-            e instanceof ApiError &&
-            e.httpStatusCode === HttpStatusCode.Unauthorized
-        ) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-};
-
-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`,
-        null,
-        {
-            'X-Auth-Token': getToken(),
-        }
-    );
-    return resp.data['status'];
-};
-
-export const _logout = async () => {
-    if (!getToken()) return true;
-    try {
-        await HTTPService.post(`${ENDPOINT}/users/logout`, null, null, {
-            'X-Auth-Token': getToken(),
-        });
-        return true;
-    } catch (e) {
-        logError(e, '/users/logout failed');
-        return false;
-    }
-};
-
-export const sendOTTForEmailChange = async (email: string) => {
-    if (!getToken()) {
-        return null;
-    }
-    await HTTPService.post(`${ENDPOINT}/users/ott`, {
-        email,
-        client: 'web',
-        purpose: 'change',
-    });
-};
-
-export const changeEmail = async (email: string, ott: string) => {
-    if (!getToken()) {
-        return null;
-    }
-    await HTTPService.post(
-        `${ENDPOINT}/users/change-email`,
-        {
-            email,
-            ott,
-        },
-        null,
-        {
-            'X-Auth-Token': getToken(),
-        }
-    );
-};
-
-export const getUserDetailsV2 = async (): Promise<UserDetails> => {
-    try {
-        const token = getToken();
-
-        const resp = await HTTPService.get(
-            `${ENDPOINT}/users/details/v2`,
-            null,
-            {
-                'X-Auth-Token': token,
-            }
-        );
-        return resp.data;
-    } catch (e) {
-        logError(e, 'failed to get user details v2');
-        throw e;
-    }
-};
-
-export const getFamilyPortalRedirectURL = async () => {
-    try {
-        const jwtToken = await getFamiliesToken();
-        const isFamilyCreated = isPartOfFamily(getLocalFamilyData());
-        return `${getFamilyPortalURL()}?token=${jwtToken}&isFamilyCreated=${isFamilyCreated}&redirectURL=${
-            window.location.origin
-        }/gallery`;
-    } catch (e) {
-        logError(e, 'unable to generate to family portal URL');
-        throw e;
-    }
-};
-
-export const getAccountDeleteChallenge = async () => {
-    try {
-        const token = getToken();
-
-        const resp = await HTTPService.get(
-            `${ENDPOINT}/users/delete-challenge`,
-            null,
-            {
-                'X-Auth-Token': token,
-            }
-        );
-        return resp.data as DeleteChallengeResponse;
-    } catch (e) {
-        logError(e, 'failed to get account delete challenge');
-        throw e;
-    }
-};
-
-export const deleteAccount = async (
-    challenge: string,
-    reason: string,
-    feedback: string
-) => {
-    try {
-        const token = getToken();
-        if (!token) {
-            return;
-        }
-
-        await HTTPService.delete(
-            `${ENDPOINT}/users/delete`,
-            { challenge, reason, feedback },
-            null,
-            {
-                'X-Auth-Token': token,
-            }
-        );
-    } catch (e) {
-        logError(e, 'deleteAccount api call failed');
-        throw e;
-    }
-};
-
-// Ensure that the keys in local storage are not malformed by verifying that the
-// recoveryKey can be decrypted with the masterKey.
-// Note: This is not bullet-proof.
-export const validateKey = async () => {
-    try {
-        await getRecoveryKey();
-        return true;
-    } catch (e) {
-        await logoutUser();
-        return false;
-    }
-};
-
-export const getFaceSearchEnabledStatus = async () => {
-    try {
-        const token = getToken();
-        const resp: AxiosResponse<GetRemoteStoreValueResponse> =
-            await HTTPService.get(
-                `${ENDPOINT}/remote-store`,
-                {
-                    key: 'faceSearchEnabled',
-                    defaultValue: false,
-                },
-                {
-                    'X-Auth-Token': token,
-                }
-            );
-        return resp.data.value === 'true';
-    } catch (e) {
-        logError(e, 'failed to get face search enabled status');
-        throw e;
-    }
-};
-
-export const updateFaceSearchEnabledStatus = async (newStatus: boolean) => {
-    try {
-        const token = getToken();
-        await HTTPService.post(
-            `${ENDPOINT}/remote-store/update`,
-            {
-                key: 'faceSearchEnabled',
-                value: newStatus.toString(),
-            },
-            null,
-            {
-                'X-Auth-Token': token,
-            }
-        );
-    } catch (e) {
-        logError(e, 'failed to update face search enabled status');
-        throw e;
-    }
-};
-
-export const syncMapEnabled = async () => {
-    try {
-        const status = await getMapEnabledStatus();
-        setLocalMapEnabled(status);
-    } catch (e) {
-        logError(e, 'failed to sync map enabled status');
-        throw e;
-    }
-};
-
-export const getMapEnabledStatus = async () => {
-    try {
-        const token = getToken();
-        const resp: AxiosResponse<GetRemoteStoreValueResponse> =
-            await HTTPService.get(
-                `${ENDPOINT}/remote-store`,
-                {
-                    key: 'mapEnabled',
-                    defaultValue: false,
-                },
-                {
-                    'X-Auth-Token': token,
-                }
-            );
-        return resp.data.value === 'true';
-    } catch (e) {
-        logError(e, 'failed to get map enabled status');
-        throw e;
-    }
-};
-
-export const updateMapEnabledStatus = async (newStatus: boolean) => {
-    try {
-        const token = getToken();
-        await HTTPService.post(
-            `${ENDPOINT}/remote-store/update`,
-            {
-                key: 'mapEnabled',
-                value: newStatus.toString(),
-            },
-            null,
-            {
-                'X-Auth-Token': token,
-            }
-        );
-    } catch (e) {
-        logError(e, 'failed to update map enabled status');
-        throw e;
-    }
-};
-
-export async function getDisableCFUploadProxyFlag(): Promise<boolean> {
-    try {
-        const disableCFUploadProxy =
-            process.env.NEXT_PUBLIC_DISABLE_CF_UPLOAD_PROXY;
-        if (isDevDeployment() && typeof disableCFUploadProxy !== 'undefined') {
-            return disableCFUploadProxy === 'true';
-        }
-        const featureFlags = (
-            await fetch('https://static.ente.io/feature_flags.json')
-        ).json() as GetFeatureFlagResponse;
-        return featureFlags.disableCFUploadProxy;
-    } catch (e) {
-        logError(e, 'failed to get feature flags');
-        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;
-};

+ 1 - 1
apps/cast/src/services/wasmHeicConverter/wasmHEICConverterService.ts

@@ -1,12 +1,12 @@
 import QueueProcessor from 'services/queueProcessor';
 import { CustomError } from 'utils/error';
 import { retryAsyncFunction } from 'utils/network';
-import { logError } from 'utils/sentry';
 import { addLogLine } from 'utils/logging';
 import { DedicatedConvertWorker } from 'worker/convert.worker';
 import { ComlinkWorker } from 'utils/comlink/comlinkWorker';
 import { convertBytesToHumanReadable } from 'utils/file/size';
 import { getDedicatedConvertWorker } from 'utils/comlink/ComlinkConvertWorker';
+import { logError } from '@ente/shared/sentry';
 
 const WORKER_POOL_SIZE = 2;
 const MAX_CONVERSION_IN_PARALLEL = 1;

+ 0 - 75
apps/cast/src/utils/sentry/index.ts

@@ -1,75 +0,0 @@
-import * as Sentry from '@sentry/nextjs';
-import { addLocalLog, addLogLine } from 'utils/logging';
-import { getSentryUserID } from 'utils/user';
-import InMemoryStore, { MS_KEYS } from 'services/InMemoryStore';
-import { getHasOptedOutOfCrashReports } from 'utils/storage';
-import { ApiError } from 'utils/error';
-
-export const logError = async (
-    error: any,
-    msg: string,
-    info?: Record<string, unknown>,
-    skipAddLogLine = false
-) => {
-    const err = errorWithContext(error, msg);
-    if (!skipAddLogLine) {
-        if (error instanceof ApiError) {
-            addLogLine(`error: ${error?.name} ${error?.message} 
-            msg: ${msg} errorCode: ${JSON.stringify(error?.errCode)}
-            httpStatusCode: ${JSON.stringify(error?.httpStatusCode)} ${
-                info ? `info: ${JSON.stringify(info)}` : ''
-            }
-            ${error?.stack}`);
-        } else {
-            addLogLine(
-                `error: ${error?.name} ${error?.message} 
-                msg: ${msg} ${info ? `info: ${JSON.stringify(info)}` : ''}
-                ${error?.stack}`
-            );
-        }
-    }
-    if (!InMemoryStore.has(MS_KEYS.OPT_OUT_OF_CRASH_REPORTS)) {
-        const optedOutOfCrashReports = getHasOptedOutOfCrashReports();
-        InMemoryStore.set(
-            MS_KEYS.OPT_OUT_OF_CRASH_REPORTS,
-            optedOutOfCrashReports
-        );
-    }
-    if (InMemoryStore.get(MS_KEYS.OPT_OUT_OF_CRASH_REPORTS)) {
-        addLocalLog(() => `skipping sentry error: ${error?.name}`);
-        return;
-    }
-    if (isErrorUnnecessaryForSentry(error)) {
-        return;
-    }
-
-    Sentry.captureException(err, {
-        level: 'info',
-        user: { id: await getSentryUserID() },
-        contexts: {
-            ...(info && {
-                info: info,
-            }),
-            rootCause: { message: error?.message, completeError: error },
-        },
-    });
-};
-
-// copy of errorWithContext to prevent importing error util
-function errorWithContext(originalError: Error, context: string) {
-    const errorWithContext = new Error(context);
-    errorWithContext.stack =
-        errorWithContext.stack.split('\n').slice(2, 4).join('\n') +
-        '\n' +
-        originalError.stack;
-    return errorWithContext;
-}
-
-function isErrorUnnecessaryForSentry(error: any) {
-    if (error?.message?.includes('Network Error')) {
-        return true;
-    } else if (error?.status === 401) {
-        return true;
-    }
-    return false;
-}

+ 0 - 40
apps/cast/src/utils/storage/index.ts

@@ -1,40 +0,0 @@
-import { Language } from 'constants/locale';
-import { getData, LS_KEYS, setData } from './localStorage';
-
-export const isFirstLogin = () =>
-    getData(LS_KEYS.IS_FIRST_LOGIN)?.status ?? false;
-
-export function setIsFirstLogin(status) {
-    setData(LS_KEYS.IS_FIRST_LOGIN, { status });
-}
-
-export const justSignedUp = () =>
-    getData(LS_KEYS.JUST_SIGNED_UP)?.status ?? false;
-
-export function setJustSignedUp(status) {
-    setData(LS_KEYS.JUST_SIGNED_UP, { status });
-}
-
-export function getLivePhotoInfoShownCount() {
-    return getData(LS_KEYS.LIVE_PHOTO_INFO_SHOWN_COUNT)?.count ?? 0;
-}
-
-export function setLivePhotoInfoShownCount(count) {
-    setData(LS_KEYS.LIVE_PHOTO_INFO_SHOWN_COUNT, { count });
-}
-
-export function getUserLocale(): Language {
-    return getData(LS_KEYS.LOCALE)?.value;
-}
-
-export function getLocalMapEnabled(): boolean {
-    return getData(LS_KEYS.MAP_ENABLED)?.value ?? false;
-}
-
-export function setLocalMapEnabled(value: boolean) {
-    setData(LS_KEYS.MAP_ENABLED, { value });
-}
-
-export function getHasOptedOutOfCrashReports(): boolean {
-    return getData(LS_KEYS.OPT_OUT_OF_CRASH_REPORTS)?.value ?? false;
-}

+ 0 - 11
apps/cast/src/utils/storage/localForage.ts

@@ -1,11 +0,0 @@
-import { runningInBrowser } from '@ente/shared/apps/browser';
-import localForage from 'localforage';
-
-if (runningInBrowser()) {
-    localForage.config({
-        name: 'ente-files',
-        version: 1.0,
-        storeName: 'files',
-    });
-}
-export default localForage;

+ 0 - 68
apps/cast/src/utils/storage/localStorage.ts

@@ -1,68 +0,0 @@
-import { logError } from 'utils/sentry';
-
-export enum LS_KEYS {
-    USER = 'user',
-    SESSION = 'session',
-    KEY_ATTRIBUTES = 'keyAttributes',
-    ORIGINAL_KEY_ATTRIBUTES = 'originalKeyAttributes',
-    SUBSCRIPTION = 'subscription',
-    FAMILY_DATA = 'familyData',
-    PLANS = 'plans',
-    IS_FIRST_LOGIN = 'isFirstLogin',
-    JUST_SIGNED_UP = 'justSignedUp',
-    SHOW_BACK_BUTTON = 'showBackButton',
-    EXPORT = 'export',
-    AnonymizedUserID = 'anonymizedUserID',
-    THUMBNAIL_FIX_STATE = 'thumbnailFixState',
-    LIVE_PHOTO_INFO_SHOWN_COUNT = 'livePhotoInfoShownCount',
-    LOGS = 'logs',
-    USER_DETAILS = 'userDetails',
-    COLLECTION_SORT_BY = 'collectionSortBy',
-    THEME = 'theme',
-    WAIT_TIME = 'waitTime',
-    API_ENDPOINT = 'apiEndpoint',
-    LOCALE = 'locale',
-    MAP_ENABLED = 'mapEnabled',
-    SRP_SETUP_ATTRIBUTES = 'srpSetupAttributes',
-    SRP_ATTRIBUTES = 'srpAttributes',
-    OPT_OUT_OF_CRASH_REPORTS = 'optOutOfCrashReports',
-    CF_PROXY_DISABLED = 'cfProxyDisabled',
-}
-
-export const setData = (key: LS_KEYS, value: object) => {
-    if (typeof localStorage === 'undefined') {
-        return null;
-    }
-    localStorage.setItem(key, JSON.stringify(value));
-};
-
-export const removeData = (key: LS_KEYS) => {
-    if (typeof localStorage === 'undefined') {
-        return null;
-    }
-    localStorage.removeItem(key);
-};
-
-export const getData = (key: LS_KEYS) => {
-    try {
-        if (
-            typeof localStorage === 'undefined' ||
-            typeof key === 'undefined' ||
-            typeof localStorage.getItem(key) === 'undefined' ||
-            localStorage.getItem(key) === 'undefined'
-        ) {
-            return null;
-        }
-        const data = localStorage.getItem(key);
-        return data && JSON.parse(data);
-    } catch (e) {
-        logError(e, 'Failed to Parse JSON for key ' + key);
-    }
-};
-
-export const clearData = () => {
-    if (typeof localStorage === 'undefined') {
-        return null;
-    }
-    localStorage.clear();
-};

+ 0 - 32
apps/cast/src/utils/storage/sessionStorage.ts

@@ -1,32 +0,0 @@
-export enum SESSION_KEYS {
-    ENCRYPTION_KEY = 'encryptionKey',
-    KEY_ENCRYPTION_KEY = 'keyEncryptionKey',
-}
-
-export const setKey = (key: SESSION_KEYS, value: object) => {
-    if (typeof sessionStorage === 'undefined') {
-        return null;
-    }
-    sessionStorage.setItem(key, JSON.stringify(value));
-};
-
-export const getKey = (key: SESSION_KEYS) => {
-    if (typeof sessionStorage === 'undefined') {
-        return null;
-    }
-    return JSON.parse(sessionStorage.getItem(key));
-};
-
-export const removeKey = (key: SESSION_KEYS) => {
-    if (typeof sessionStorage === 'undefined') {
-        return null;
-    }
-    sessionStorage.removeItem(key);
-};
-
-export const clearKeys = () => {
-    if (typeof sessionStorage === 'undefined') {
-        return null;
-    }
-    sessionStorage.clear();
-};

+ 0 - 45
apps/cast/src/utils/user/family.ts

@@ -1,45 +0,0 @@
-import { FamilyData, FamilyMember, User } from 'types/user';
-import { logError } from 'utils/sentry';
-import { getData, LS_KEYS } from 'utils/storage/localStorage';
-
-export function getLocalFamilyData(): FamilyData {
-    return getData(LS_KEYS.FAMILY_DATA);
-}
-
-// isPartOfFamily return true if the current user is part of some family plan
-export function isPartOfFamily(familyData: FamilyData): boolean {
-    return Boolean(
-        familyData && familyData.members && familyData.members.length > 0
-    );
-}
-
-// hasNonAdminFamilyMembers return true if the admin user has members in his family
-export function hasNonAdminFamilyMembers(familyData: FamilyData): boolean {
-    return Boolean(isPartOfFamily(familyData) && familyData.members.length > 1);
-}
-
-export function isFamilyAdmin(familyData: FamilyData): boolean {
-    const familyAdmin: FamilyMember = getFamilyPlanAdmin(familyData);
-    const user: User = getData(LS_KEYS.USER);
-    return familyAdmin.email === user.email;
-}
-
-export function getFamilyPlanAdmin(familyData: FamilyData): FamilyMember {
-    if (isPartOfFamily(familyData)) {
-        return familyData.members.find((x) => x.isAdmin);
-    } else {
-        logError(
-            Error(
-                'verify user is part of family plan before calling this method'
-            ),
-            'invalid getFamilyPlanAdmin call'
-        );
-    }
-}
-
-export function getTotalFamilyUsage(familyData: FamilyData): number {
-    return familyData.members.reduce(
-        (sum, currentMember) => sum + currentMember.usage,
-        0
-    );
-}

+ 0 - 52
apps/cast/src/utils/user/index.ts

@@ -1,52 +0,0 @@
-import isElectron from 'is-electron';
-import { UserDetails } from 'types/user';
-import { getData, LS_KEYS, setData } from 'utils/storage/localStorage';
-// import ElectronService from 'services/electron/common';
-import { Buffer } from 'buffer';
-
-export function makeID(length) {
-    let result = '';
-    const characters =
-        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
-    const charactersLength = characters.length;
-    for (let i = 0; i < length; i++) {
-        result += characters.charAt(
-            Math.floor(Math.random() * charactersLength)
-        );
-    }
-    return result;
-}
-
-export async function getSentryUserID() {
-    if (isElectron()) {
-        // return await ElectronService.getSentryUserID();
-    } else {
-        let anonymizeUserID = getData(LS_KEYS.AnonymizedUserID)?.id;
-        if (!anonymizeUserID) {
-            anonymizeUserID = makeID(6);
-            setData(LS_KEYS.AnonymizedUserID, { id: anonymizeUserID });
-        }
-        return anonymizeUserID;
-    }
-}
-
-export function getLocalUserDetails(): UserDetails {
-    return getData(LS_KEYS.USER_DETAILS)?.value;
-}
-
-export const isInternalUser = () => {
-    const userEmail = getData(LS_KEYS.USER)?.email;
-    if (!userEmail) return false;
-
-    return (
-        userEmail.endsWith('@ente.io') || userEmail === 'kr.anand619@gmail.com'
-    );
-};
-
-export const convertBufferToBase64 = (buffer: Buffer) => {
-    return buffer.toString('base64');
-};
-
-export const convertBase64ToBuffer = (base64: string) => {
-    return Buffer.from(base64, 'base64');
-};