diff --git a/lib/facts/backup-service.js b/lib/facts/backup-service.js deleted file mode 100644 --- a/lib/facts/backup-service.js +++ /dev/null @@ -1,52 +0,0 @@ -// @flow - -import { isDev } from '../utils/dev-utils.js'; - -type BackupServiceEndpointPath = - | '/backups' - | '/backups/:backupID/user_keys' - | '/backups/:backupID/user_data' - | '/backups/latest/:username/backup_id' - | '/backups/latest/:username/user_keys'; - -export type BackupServiceHTTPEndpoint = { - +path: BackupServiceEndpointPath, - +method: 'GET' | 'POST', -}; - -const httpEndpoints = Object.freeze({ - // endpoints with auth - UPLOAD_BACKUP: { - path: '/backups', - method: 'POST', - }, - GET_USER_KEYS: { - path: '/backups/:backupID/user_keys', - method: 'GET', - }, - GET_USER_DATA: { - path: '/backups/:backupID/user_data', - method: 'GET', - }, - // endpoints without auth - GET_LATEST_BACKUP_ID: { - path: '/backups/latest/:username/backup_id', - method: 'GET', - }, - GET_LATEST_USER_KEYS: { - path: '/backups/latest/:username/user_keys', - method: 'GET', - }, -}); - -const config: { - url: string, - httpEndpoints: { +[endpoint: string]: BackupServiceHTTPEndpoint }, -} = { - url: isDev - ? 'https://backup.staging.commtechnologies.org' - : 'https://backup.commtechnologies.org', - httpEndpoints, -}; - -export default config; diff --git a/lib/types/backup-types.js b/lib/types/backup-types.js deleted file mode 100644 --- a/lib/types/backup-types.js +++ /dev/null @@ -1,30 +0,0 @@ -// @flow - -import type { UserStore } from './user-types.js'; - -export type UserKeys = { - +backupDataKey: string, - +ed25519: string, -}; - -export type UserData = { - +userStore: UserStore, -}; - -export type BackupAuth = { - +userID: string, - +accessToken: string, - +deviceID: string, -}; - -export type Backup = { - +backupID: string, - +userKeys: UserKeys, - +userData: UserData, -}; - -export type BackupEncrypted = { - +backupID: string, - +userKeys: string, - +userData: string, -}; diff --git a/lib/utils/backup-service.js b/lib/utils/backup-service.js deleted file mode 100644 --- a/lib/utils/backup-service.js +++ /dev/null @@ -1,15 +0,0 @@ -// @flow - -import { replacePathParams, type URLPathParams } from './url-utils.js'; -import backupServiceConfig from '../facts/backup-service.js'; -import type { BackupServiceHTTPEndpoint } from '../facts/backup-service.js'; - -function makeBackupServiceEndpointURL( - endpoint: BackupServiceHTTPEndpoint, - params: URLPathParams = {}, -): string { - const path = replacePathParams(endpoint.path, params); - return `${backupServiceConfig.url}${path}`; -} - -export { makeBackupServiceEndpointURL }; diff --git a/native/backup/api.js b/native/backup/api.js deleted file mode 100644 --- a/native/backup/api.js +++ /dev/null @@ -1,119 +0,0 @@ -// @flow - -import base64 from 'base-64'; - -import backupService from 'lib/facts/backup-service.js'; -import type { BackupAuth, BackupEncrypted } from 'lib/types/backup-types.js'; -import { makeBackupServiceEndpointURL } from 'lib/utils/backup-service.js'; -import { toBase64URL } from 'lib/utils/base64.js'; -import { handleHTTPResponseError } from 'lib/utils/services-utils.js'; - -import { getBackupStringFromBlob } from './conversion-utils.js'; -import { commUtilsModule } from '../native-modules.js'; - -function getBackupFormData(backup: BackupEncrypted): FormData { - const { backupID, userKeys, userData } = backup; - const userKeysHash = commUtilsModule.sha256( - commUtilsModule.encodeStringToUTF8ArrayBuffer(userKeys), - ); - const userDataHash = commUtilsModule.sha256( - commUtilsModule.encodeStringToUTF8ArrayBuffer(userData), - ); - - const formData = new FormData(); - formData.append('backup_id', backupID); - formData.append('user_keys_hash', toBase64URL(userKeysHash)); - formData.append('user_keys', backup.userKeys); - formData.append('user_data_hash', toBase64URL(userDataHash)); - formData.append('user_data', backup.userData); - formData.append('attachments', ''); - return formData; -} - -function getBackupAuthorizationHeader(auth: BackupAuth) { - const authStr = JSON.stringify(auth); - const authBase64 = base64.encode(authStr); - return `Bearer ${authBase64}`; -} - -async function uploadBackup(backup: BackupEncrypted, auth: BackupAuth) { - const authHeader = getBackupAuthorizationHeader(auth); - - const uploadBackupEndpoint = backupService.httpEndpoints.UPLOAD_BACKUP; - const sendBackupResponse = await fetch( - makeBackupServiceEndpointURL(uploadBackupEndpoint), - { - method: uploadBackupEndpoint.method, - body: getBackupFormData(backup), - headers: { - 'Content-Type': 'multipart/form-data', - 'Authorization': authHeader, - }, - }, - ); - - handleHTTPResponseError(sendBackupResponse); -} - -async function getBackupID(username: string): Promise { - const getBackupIDEndpoint = backupService.httpEndpoints.GET_LATEST_BACKUP_ID; - const getBackupIDResponse = await fetch( - makeBackupServiceEndpointURL(getBackupIDEndpoint, { username }), - { - method: getBackupIDEndpoint.method, - }, - ); - - handleHTTPResponseError(getBackupIDResponse); - - const { backupID } = await getBackupIDResponse.json(); - return backupID; -} - -async function getUserKeys( - backupID: string, - auth: BackupAuth, -): Promise { - const authHeader = getBackupAuthorizationHeader(auth); - - const getUserKeysEndpoint = backupService.httpEndpoints.GET_USER_KEYS; - const getUserKeysResponse = await fetch( - makeBackupServiceEndpointURL(getUserKeysEndpoint, { backupID }), - { - method: getUserKeysEndpoint.method, - headers: { - Authorization: authHeader, - }, - }, - ); - - handleHTTPResponseError(getUserKeysResponse); - - const blob = await getUserKeysResponse.blob(); - return getBackupStringFromBlob(blob); -} - -async function getUserData( - backupID: string, - auth: BackupAuth, -): Promise { - const authHeader = getBackupAuthorizationHeader(auth); - - const getUserDataEndpoint = backupService.httpEndpoints.GET_USER_DATA; - const getUserDataResponse = await fetch( - makeBackupServiceEndpointURL(getUserDataEndpoint, { backupID }), - { - method: getUserDataEndpoint.method, - headers: { - Authorization: authHeader, - }, - }, - ); - - handleHTTPResponseError(getUserDataResponse); - - const blob = await getUserDataResponse.blob(); - return getBackupStringFromBlob(blob); -} - -export { uploadBackup, getBackupID, getUserKeys, getUserData }; diff --git a/native/backup/backup-handler.js b/native/backup/backup-handler.js --- a/native/backup/backup-handler.js +++ b/native/backup/backup-handler.js @@ -31,6 +31,12 @@ const { uploadBackupProtocol } = useClientBackup(); + React.useEffect(() => { + if (!isBackupEnabled) { + AsyncStorage.removeItem(BACKUP_HASH_STORAGE_KEY); + } + }, [isBackupEnabled]); + React.useEffect(() => { void (async () => { if ( @@ -61,10 +67,11 @@ currentBackupHash, ); } catch (e) { - console.error(`Backup uploading error: ${e}`); + const message = String(getMessageForException(e)); + console.error(`Backup uploading error: ${message}`); Alert.alert( 'Backup protocol info', - `Backup uploading error: ${String(getMessageForException(e))}`, + `Backup uploading error: ${message}`, ); } } diff --git a/native/backup/conversion-utils.js b/native/backup/conversion-utils.js --- a/native/backup/conversion-utils.js +++ b/native/backup/conversion-utils.js @@ -1,12 +1,6 @@ // @flow import { commUtilsModule } from '../native-modules.js'; -import { arrayBufferFromBlob } from '../utils/blob-utils-module.js'; - -function getBackupStringFromBlob(blob: Blob): string { - const buffer = arrayBufferFromBlob(blob); - return commUtilsModule.decodeUTF8ArrayBufferToString(buffer); -} function convertObjToBytes(obj: T): Uint8Array { const objStr = JSON.stringify(obj); @@ -19,4 +13,4 @@ return JSON.parse(str); } -export { getBackupStringFromBlob, convertObjToBytes, convertBytesToObj }; +export { convertObjToBytes, convertBytesToObj }; diff --git a/native/backup/use-client-backup.js b/native/backup/use-client-backup.js --- a/native/backup/use-client-backup.js +++ b/native/backup/use-client-backup.js @@ -4,13 +4,17 @@ import * as React from 'react'; import { isLoggedIn } from 'lib/selectors/user-selectors.js'; -import type { UserData } from 'lib/types/backup-types.js'; +import type { UserStore } from 'lib/types/user-types.js'; import { fetchNativeKeychainCredentials } from '../account/native-credentials.js'; import { commCoreModule } from '../native-modules.js'; import { useSelector } from '../redux/redux-utils.js'; import { getContentSigningKey } from '../utils/crypto-utils.js'; +type UserData = { + +userStore: UserStore, +}; + type ClientBackup = { +uploadBackupProtocol: (userData: UserData) => Promise, +restoreBackupProtocol: ( diff --git a/native/profile/backup-menu.react.js b/native/profile/backup-menu.react.js --- a/native/profile/backup-menu.react.js +++ b/native/profile/backup-menu.react.js @@ -41,8 +41,8 @@ .map(([key, value]) => `${key}: ${String(value)}`) .join('\n'); } catch (e) { - console.error(`Backup uploading error: ${e}`); message = `Backup restore error: ${String(getMessageForException(e))}`; + console.error(message); } Alert.alert('Restore protocol result', message); }, [restoreBackupProtocol, userStore]);