mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-10 14:07:59 -05:00
INJI-633: backup upload to cloud and download from cloud
Signed-off-by: Sreenadh S <32409698+sree96@users.noreply.github.com>
This commit is contained in:
@@ -8,7 +8,6 @@ import {
|
||||
} from '../shared/storage';
|
||||
import {
|
||||
compressAndRemoveFile,
|
||||
uploadBackupFileToDrive,
|
||||
} from '../shared/fileStorage';
|
||||
import {
|
||||
getEndEventData,
|
||||
@@ -19,6 +18,8 @@ import {
|
||||
sendStartEvent,
|
||||
} from '../shared/telemetry/TelemetryUtils';
|
||||
import {TelemetryConstants} from '../shared/telemetry/TelemetryConstants';
|
||||
import Cloud from "../shared/googleCloudUtils";
|
||||
import {UPLOAD_MAX_RETRY} from "../shared/constants";
|
||||
import {bytesToMB} from '../shared/commonUtil';
|
||||
import {BackupFileMeta} from '../types/backup-and-restore/backup';
|
||||
|
||||
@@ -114,10 +115,8 @@ export const backupMachine = model.createMachine(
|
||||
invoke: {
|
||||
src: 'zipBackupFile',
|
||||
onDone: {
|
||||
//TODO: change target to uploadBackupFile (Moving to success for local testing)
|
||||
actions: 'extractBackupSuccessMetaData',
|
||||
target: 'success',
|
||||
// target: 'uploadBackupFile',
|
||||
actions: 'extractBackupSuccessMetaData',
|
||||
target: 'uploadBackupFile',
|
||||
},
|
||||
onError: {
|
||||
target: 'failure',
|
||||
@@ -244,7 +243,7 @@ export const backupMachine = model.createMachine(
|
||||
return result;
|
||||
},
|
||||
uploadBackupFile: context => async () => {
|
||||
const result = await uploadBackupFileToDrive(context.fileName);
|
||||
const result = await Cloud.uploadBackupFileToDrive(context.fileName,UPLOAD_MAX_RETRY);
|
||||
return result;
|
||||
},
|
||||
},
|
||||
|
||||
@@ -23,8 +23,7 @@ export const BACKUP_ENC_KEY_TYPE = 'backupEncKeyType';
|
||||
export const BACKUP_ENC_TYPE_VAL_PASSWORD = 'password';
|
||||
|
||||
export const BACKUP_ENC_TYPE_VAL_PHONE = 'phone';
|
||||
|
||||
export const GCLOUD_BACKUP_DIR_NAME = 'backup';
|
||||
export const UPLOAD_MAX_RETRY = 2;
|
||||
|
||||
export let individualId = {id: '', idType: 'UIN' as VcIdType};
|
||||
|
||||
|
||||
@@ -10,13 +10,7 @@ import {
|
||||
writeFile,
|
||||
} from 'react-native-fs';
|
||||
import * as RNZipArchive from 'react-native-zip-archive';
|
||||
import {CloudStorage, CloudStorageScope} from 'react-native-cloud-storage';
|
||||
import {GCLOUD_BACKUP_DIR_NAME} from './constants';
|
||||
import Cloud, {getToken, removeOldDriveBackupFiles} from './googleCloudUtils';
|
||||
import {
|
||||
GDrive,
|
||||
MimeTypes,
|
||||
} from '@robinbobin/react-native-google-drive-api-wrapper';
|
||||
|
||||
interface CacheData {
|
||||
data?: any;
|
||||
count?: number;
|
||||
@@ -86,35 +80,6 @@ export async function compressAndRemoveFile(fileName: string): Promise<StatResul
|
||||
return backupFileMeta;
|
||||
}
|
||||
|
||||
export async function uploadBackupFileToDrive(
|
||||
fileName: string,
|
||||
): Promise<string> {
|
||||
try {
|
||||
console.log('uploadBackupFileToDrive');
|
||||
const tokenResult = await Cloud.getAccessToken();
|
||||
console.log('uploadBackupFileToDrive tokenResult ', tokenResult);
|
||||
const filePath = zipFilePath(fileName);
|
||||
|
||||
//read file
|
||||
const fileContent = await readFile(filePath, 'base64');
|
||||
console.log('Read file success ');
|
||||
// upload file
|
||||
CloudStorage.setGoogleDriveAccessToken(tokenResult)
|
||||
await CloudStorage.writeFile(`/${fileName}.zip`,fileContent)
|
||||
console.log('write file success ');
|
||||
|
||||
var files = await CloudStorage.readdir('/')
|
||||
console.log('files', files)
|
||||
|
||||
//remove old files
|
||||
// await removeOldDriveBackupFiles(fileName);
|
||||
return Promise.resolve('success');
|
||||
} catch (error) {
|
||||
console.log('Error while uploadBackupFileToDrive ', error);
|
||||
return Promise.reject('failure');
|
||||
}
|
||||
}
|
||||
|
||||
async function compressFile(fileName: string): Promise<string> {
|
||||
return await RNZipArchive.zip(backupDirectoryPath, zipFilePath(fileName));
|
||||
}
|
||||
|
||||
@@ -1,64 +1,57 @@
|
||||
import {
|
||||
GoogleSignin,
|
||||
statusCodes,
|
||||
} from '@react-native-google-signin/google-signin';
|
||||
import { GoogleSignin, statusCodes } from '@react-native-google-signin/google-signin';
|
||||
import {CloudStorage, CloudStorageScope} from 'react-native-cloud-storage';
|
||||
import {GOOGLE_ANDROID_CLIENT_ID} from 'react-native-dotenv';
|
||||
import {request} from '../shared/request';
|
||||
import {GCLOUD_BACKUP_DIR_NAME} from './constants';
|
||||
|
||||
export const getToken = async (): Promise<string> => {
|
||||
try {
|
||||
await GoogleSignin.configure({
|
||||
scopes: [
|
||||
'https://www.googleapis.com/auth/drive.appdata',
|
||||
'https://www.googleapis.com/auth/drive.file',
|
||||
], // what API you want to access on behalf of the user, default is email and profile
|
||||
androidClientId: GOOGLE_ANDROID_CLIENT_ID, // client ID of type WEB for your server. Required to get the idToken on the user object, and for offline access.
|
||||
});
|
||||
await GoogleSignin.signIn();
|
||||
const tokenResult = await GoogleSignin.getTokens();
|
||||
console.log('GoogleSignin result ', JSON.stringify(tokenResult, null, 2));
|
||||
return tokenResult.accessToken;
|
||||
} catch (error) {
|
||||
console.error('Error while getting token ', error);
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
export const removeOldDriveBackupFiles = async (fileName: string) => {
|
||||
const allFiles = await CloudStorage.readdir(
|
||||
`${GCLOUD_BACKUP_DIR_NAME}`,
|
||||
CloudStorageScope.AppData,
|
||||
);
|
||||
console.log('allFiles ', allFiles);
|
||||
return;
|
||||
for (const oldFileName of allFiles.filter(file => file != fileName)) {
|
||||
await CloudStorage.unlink(`${GCLOUD_BACKUP_DIR_NAME}/${oldFileName}`);
|
||||
}
|
||||
};
|
||||
import {request} from './request';
|
||||
import {readFile} from "react-native-fs";
|
||||
import {zipFilePath} from "./fileStorage";
|
||||
|
||||
class Cloud {
|
||||
private static configured = false;
|
||||
static status = {
|
||||
DECLINED: 'DECLINED',
|
||||
SUCCESS: 'SUCCESS',
|
||||
FAILURE: 'FAILURE',
|
||||
};
|
||||
|
||||
private static async configure(): Promise<void> {
|
||||
await GoogleSignin.configure({
|
||||
private static configure() {
|
||||
GoogleSignin.configure({
|
||||
scopes: [
|
||||
'https://www.googleapis.com/auth/drive.appdata',
|
||||
'https://www.googleapis.com/auth/drive.file',
|
||||
], // what API you want to access on behalf of the user, default is email and profile
|
||||
androidClientId: GOOGLE_ANDROID_CLIENT_ID, // client ID of type WEB for your server. Required to get the idToken on the user object, and for offline access.
|
||||
],
|
||||
androidClientId: GOOGLE_ANDROID_CLIENT_ID,
|
||||
});
|
||||
this.configured = true;
|
||||
}
|
||||
|
||||
private static async profileInfo(): Promise<ProfileInfo | undefined> {
|
||||
try {
|
||||
const accessToken = await this.getAccessToken();
|
||||
const profileResponse = await request(
|
||||
'GET',
|
||||
`https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${accessToken}`,
|
||||
undefined,
|
||||
'',
|
||||
);
|
||||
return {
|
||||
email: profileResponse.email,
|
||||
picture: profileResponse.picture,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error while getting profile info ', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
static async getAccessToken() {
|
||||
try {
|
||||
const tokenResult = await GoogleSignin.getTokens();
|
||||
await GoogleSignin.clearCachedAccessToken(tokenResult.accessToken);
|
||||
await GoogleSignin.signInSilently();
|
||||
const {accessToken} = await GoogleSignin.getTokens();
|
||||
return accessToken;
|
||||
} catch (error) {
|
||||
console.error('Error while getting access token ', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
static async signIn(): Promise<SignInResult> {
|
||||
this.initialize();
|
||||
this.configure();
|
||||
try {
|
||||
await GoogleSignin.signIn();
|
||||
const profileInfo = await this.profileInfo();
|
||||
@@ -79,10 +72,9 @@ class Cloud {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static async isSignedInAlready(): Promise<isSignedInResult> {
|
||||
try {
|
||||
this.initialize();
|
||||
this.configure();
|
||||
const isSignedIn = await GoogleSignin.isSignedIn();
|
||||
if (!isSignedIn) {
|
||||
await GoogleSignin.signInSilently();
|
||||
@@ -110,43 +102,45 @@ class Cloud {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static initialize(): void {
|
||||
this.configure();
|
||||
}
|
||||
|
||||
private static async profileInfo(): Promise<ProfileInfo | undefined> {
|
||||
try {
|
||||
const accessToken = await this.getAccessToken();
|
||||
const profileResponse = await request(
|
||||
'GET',
|
||||
`https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${accessToken}`,
|
||||
undefined,
|
||||
'',
|
||||
);
|
||||
return {
|
||||
email: profileResponse.email,
|
||||
picture: profileResponse.picture,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error while getting profile info ', error);
|
||||
throw error;
|
||||
static async removeOldDriveBackupFiles(fileName: string){
|
||||
const allFiles = await CloudStorage.readdir(`/`, CloudStorageScope.AppData);
|
||||
for (const oldFileName of allFiles.filter(file => file != fileName)) {
|
||||
await CloudStorage.unlink(`/${oldFileName}`);
|
||||
}
|
||||
}
|
||||
static async uploadBackupFileToDrive(fileName: string, retryCounter: number): Promise<string> {
|
||||
if (retryCounter < 0) return Promise.reject("failure");
|
||||
|
||||
const cloudFileName = `/${fileName}.zip`;
|
||||
|
||||
public static async getAccessToken() {
|
||||
try {
|
||||
const tokenResult = await GoogleSignin.getTokens();
|
||||
await GoogleSignin.clearCachedAccessToken(tokenResult.accessToken);
|
||||
const {accessToken} = await GoogleSignin.getTokens();
|
||||
return accessToken;
|
||||
const tokenResult = await Cloud.getAccessToken();
|
||||
CloudStorage.setGoogleDriveAccessToken(tokenResult);
|
||||
|
||||
const filePath = zipFilePath(fileName);
|
||||
const fileContent = await readFile(filePath, 'base64');
|
||||
|
||||
await CloudStorage.writeFile(cloudFileName,fileContent,CloudStorageScope.AppData);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error while getting access token ', error);
|
||||
throw error;
|
||||
console.log(`Error occured while cloud upload.. retrying ${retryCounter} : Error : ${error}`);
|
||||
}
|
||||
|
||||
const isFileUploaded = await CloudStorage.exists(cloudFileName,CloudStorageScope.AppData);
|
||||
|
||||
if (isFileUploaded){
|
||||
console.log("file is there") // remove
|
||||
await this.removeOldDriveBackupFiles(cloudFileName);
|
||||
return Promise.resolve('success');
|
||||
}
|
||||
return this.uploadBackupFileToDrive(fileName,retryCounter - 1);
|
||||
}
|
||||
static async downloadLatestBackup(): Promise<string> {
|
||||
const allFiles = await CloudStorage.readdir(`/`, CloudStorageScope.AppData);
|
||||
const fileContent = await CloudStorage.readFile(allFiles[0]);
|
||||
return Promise.resolve(fileContent);
|
||||
}
|
||||
}
|
||||
|
||||
export default Cloud;
|
||||
|
||||
export type ProfileInfo = {
|
||||
|
||||
Reference in New Issue
Block a user