From 0ab13db14950fb32e6b2d3717030c7ad996ff52d Mon Sep 17 00:00:00 2001 From: Piyush Upadhyay Date: Mon, 24 Jun 2024 18:42:29 +0530 Subject: [PATCH 1/6] added google login and drive api wrapper dependency Signed-off-by: Piyush Upadhyay --- package.json | 2 ++ yarn.lock | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c331e14a..f5331306 100644 --- a/package.json +++ b/package.json @@ -34,11 +34,13 @@ "@react-native-community/netinfo": "^9.4.1", "@react-native-firebase/app": "^18.4.0", "@react-native-firebase/messaging": "^18.4.0", + "@react-native-google-signin/google-signin": "12.1.0", "@react-navigation/bottom-tabs": "^6.5.8", "@react-navigation/core": "^6.4.9", "@react-navigation/devtools": "^6.0.19", "@react-navigation/native": "^6.1.7", "@react-navigation/stack": "^6.3.17", + "@robinbobin/react-native-google-drive-api-wrapper": "^1.2.4", "axios": "^1.6.0", "bip39": "^3.1.0", "events": "^1.1.1", diff --git a/yarn.lock b/yarn.lock index 1ceb0f3a..850488a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3019,6 +3019,11 @@ resolved "https://registry.yarnpkg.com/@react-native-firebase/messaging/-/messaging-18.4.0.tgz#7f05bbfa6841f84e96d97935f33ac9638bee346c" integrity sha512-oVxOHRmLrdEXBVHgnrTkzWFiL/SbXi9oaXf/kYuqgcMGkupIhBNpPxvnqq4Z1QO0d9huZp0KHDeTgNEwA5hq1Q== +"@react-native-google-signin/google-signin@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@react-native-google-signin/google-signin/-/google-signin-12.1.0.tgz#9111dc068d1ec40b1b24d73ca5c0b171ba08e543" + integrity sha512-Vn2zXCAz0Vh43xEtFebqd0wGvQWXGPkTZvfff/3V7+5BQKR7nL52mlry10llCLNRiVDDz0oWoBGETifpBz7W8A== + "@react-native/assets-registry@^0.72.0": version "0.72.0" resolved "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.72.0.tgz" @@ -3157,6 +3162,15 @@ color "^4.2.3" warn-once "^0.1.0" +"@robinbobin/react-native-google-drive-api-wrapper@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@robinbobin/react-native-google-drive-api-wrapper/-/react-native-google-drive-api-wrapper-1.2.4.tgz#b5c0c30c3754b9abba9034897b66a4afd7f1755c" + integrity sha512-X4qa6mmINpOU/1KCV7xa+NGKmKOtBKyqvlkuntmXg6RDq+7ojYH4fhH/dO/wKMss6n77kDrT9WPKW/zdsc9ESQ== + dependencies: + base64-js "^1.5.1" + simple-common-utils "^2.3.0" + utf8 "^3.0.0" + "@sd-jwt/core@^0.6.1": version "0.6.1" resolved "https://registry.yarnpkg.com/@sd-jwt/core/-/core-0.6.1.tgz#d28be10d0f4b672636fcf7ad71737cb08e5dae96" @@ -4406,7 +4420,7 @@ base-64@0.1.0, base-64@^0.1.0: resolved "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz" integrity sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA== -base64-js@*, base64-js@^1.0.2, base64-js@^1.1.2, base64-js@^1.3.0, base64-js@^1.3.1: +base64-js@*, base64-js@^1.0.2, base64-js@^1.1.2, base64-js@^1.3.0, base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -10593,6 +10607,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +simple-common-utils@^2.3.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/simple-common-utils/-/simple-common-utils-2.6.0.tgz#457f126c20c82ba10212427886f4c8ebe86cc6d7" + integrity sha512-K0gtyfMQ1+iDQvZKgdY2L+pbaG0MHp1ke6ho7IL6UKR8f59st+QJgw27FADF+3Hut19C3WUb7IhgENdY/OJG8w== + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" From 3a64aa23d4531973eadc70a58a77e4bc42c8fe6f Mon Sep 17 00:00:00 2001 From: Piyush Upadhyay Date: Mon, 24 Jun 2024 18:52:32 +0530 Subject: [PATCH 2/6] Updated .gitignore to exclude vs code files Signed-off-by: Piyush Upadhyay --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 2b2c9587..d8a221e3 100644 --- a/.gitignore +++ b/.gitignore @@ -68,3 +68,5 @@ yarn-error.log .env google-services.json +# VS Code +.vscode/ \ No newline at end of file From 67a5e64f94544afb7ae8857955049fb673cc96f9 Mon Sep 17 00:00:00 2001 From: Piyush Upadhyay Date: Mon, 24 Jun 2024 19:09:02 +0530 Subject: [PATCH 3/6] google login functionality Signed-off-by: Piyush Upadhyay --- App.tsx | 8 +++++ app/contexts/auth.tsx | 35 +++++++++++++++++- app/localization/en/index.ts | 17 +++++++-- app/navigators/SettingStack.tsx | 6 ++++ app/screens/ExportWallet.tsx | 6 ++-- app/screens/GoogleDriveSignIn.tsx | 60 +++++++++++++++++++++++++++++++ app/screens/Settings.tsx | 32 ++++++++++++++++- app/types/navigators.ts | 1 + 8 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 app/screens/GoogleDriveSignIn.tsx diff --git a/App.tsx b/App.tsx index 1c7febee..95f84f88 100644 --- a/App.tsx +++ b/App.tsx @@ -2,9 +2,11 @@ global.Buffer = require('buffer').Buffer import { AdeyaAgentProvider } from '@adeya/ssi' +import { GoogleSignin } from '@react-native-google-signin/google-signin' import * as React from 'react' import { useEffect, useMemo } from 'react' import { StatusBar } from 'react-native' +import { Config } from 'react-native-config' import SplashScreen from 'react-native-splash-screen' import Toast from 'react-native-toast-message' @@ -38,6 +40,12 @@ const App = () => { // Hide the native splash / loading screen so that our // RN version can be displayed SplashScreen.hide() + GoogleSignin.configure({ + webClientId: Config.GOOGLE_WEB_CLIENT_ID, + iosClientId: Config.GOOGLE_IOS_CLIENT_ID, + offlineAccess: true, + scopes: ['https://www.googleapis.com/auth/drive.file', 'https://www.googleapis.com/auth/drive.metadata'], + }) }, []) return ( diff --git a/app/contexts/auth.tsx b/app/contexts/auth.tsx index 87088413..29fd6253 100644 --- a/app/contexts/auth.tsx +++ b/app/contexts/auth.tsx @@ -2,7 +2,9 @@ import 'reflect-metadata' import { isWalletPinCorrect } from '@adeya/ssi' -import React, { PropsWithChildren, createContext, useContext, useState } from 'react' +import AsyncStorage from '@react-native-async-storage/async-storage' +import { GoogleSignin } from '@react-native-google-signin/google-signin' +import React, { PropsWithChildren, createContext, useContext, useState, useEffect } from 'react' import { useTranslation } from 'react-i18next' import { DeviceEventEmitter } from 'react-native' @@ -29,15 +31,43 @@ export interface AuthContext { setPIN: (PIN: string) => Promise commitPIN: (useBiometry: boolean) => Promise isBiometricsActive: () => Promise + isSignedIn: boolean + signIn: () => Promise + signOut: () => Promise } export const AuthContext = createContext(null as unknown as AuthContext) export const AuthProvider: React.FC = ({ children }) => { const [walletSecret, setWalletSecret] = useState() + const [isSignedIn, setIsSignedIn] = useState(false) const [, dispatch] = useStore() const { t } = useTranslation() + useEffect(() => { + const checkSignInStatus = async () => { + const userInfo = await AsyncStorage.getItem('userInfo') + setIsSignedIn(userInfo !== null) + } + checkSignInStatus() + }, []) + + const signIn = async (): Promise => { + // const userInfo = await GoogleSignin.signIn() + // await AsyncStorage.setItem('userInfo', JSON.stringify(userInfo)) + setIsSignedIn(true) + } + + const signOut = async (): Promise => { + try { + await GoogleSignin.signOut() + await AsyncStorage.removeItem('userInfo') + setIsSignedIn(false) + } catch (error) { + // error message + } + } + const setPIN = async (PIN: string): Promise => { const secret = await secretForPIN(PIN) await storeWalletSecret(secret) @@ -128,6 +158,9 @@ export const AuthProvider: React.FC = ({ children }) => { commitPIN, setPIN, isBiometricsActive, + isSignedIn, + signIn, + signOut, }}> {children} diff --git a/app/localization/en/index.ts b/app/localization/en/index.ts index 65b01f60..81e3c52b 100644 --- a/app/localization/en/index.ts +++ b/app/localization/en/index.ts @@ -486,6 +486,7 @@ const translation = { "ScanMyQR": "Scan my QR code", "Developer": "Developer options", "Backup": "backup wallet", + "GoogleDriveBackup": "Google Drive Backup", "Confirmation" : 'Confirmation' }, "TabStack": { @@ -568,7 +569,8 @@ const translation = { "ProofChangeCredential": "Choose a credential", "DataRetention": "Data retention", "Organization": "Explore", - "OrganizationConnection": "Connection" + "OrganizationConnection": "Connection", + "GoogleDriveSignIn": "Google Drive Sign In", }, "Loading": { "TakingTooLong": "This is taking longer than usual. You can return to home or continue waiting.", @@ -692,6 +694,7 @@ const translation = { "you_have_successfully": 'You have successfully selected the words.', "complete_backup": 'Complete Backup', "backup_wallet": 'Backup Wallet', + "backup_google_drive": 'Backup to Google Drive', }, "PushNotifications": { "BulletFour": "new messages", @@ -707,7 +710,17 @@ const translation = { }, "DIDs":{ "Dids": "My DID", - } + }, + "GoogleDrive": { + "Backup": "Backup to Google Drive", + "BackupTitle": "Backup to Google Drive", + "SignInCancelled": "User cancelled the login flow", + "SignInProgress": "Operation is in progress already", + "PlayServicesNotAvailable": "Play services not available or outdated", + "SignInError": "An error occurred during sign-in", + "SignOutGoogle": "Sign Out of Google Account", + "SignOutGoogleSuccess": "Google Sign Out Successful", + }, } export default translation diff --git a/app/navigators/SettingStack.tsx b/app/navigators/SettingStack.tsx index 3ccba712..2a241b21 100644 --- a/app/navigators/SettingStack.tsx +++ b/app/navigators/SettingStack.tsx @@ -10,6 +10,7 @@ import CreateWallet from '../screens/CreateWallet' import DataRetention from '../screens/DataRetention' import ExportWallet from '../screens/ExportWallet' import ExportWalletConfirmation from '../screens/ExportWalletConfirmation' +import GoogleDriveSignIn from '../screens/GoogleDriveSignIn' import ImportSuccess from '../screens/ImportSuccess' import ImportWalletVerify from '../screens/ImportWalletConfirmation' import Language from '../screens/Language' @@ -137,6 +138,11 @@ const SettingStack: React.FC = () => { component={CreateWallet} options={{ title: t('Screens.CreateWallet') }} /> + ) } diff --git a/app/screens/ExportWallet.tsx b/app/screens/ExportWallet.tsx index 0a1cd21b..28b5b5a3 100644 --- a/app/screens/ExportWallet.tsx +++ b/app/screens/ExportWallet.tsx @@ -1,5 +1,5 @@ import { addWalletRecord, findWalletRecordsByQuery, useAdeyaAgent, utils } from '@adeya/ssi' -import { useNavigation } from '@react-navigation/core' +import { useNavigation, useRoute } from '@react-navigation/core' import { generateMnemonic } from 'bip39' import React, { useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -15,6 +15,8 @@ const ExportWallet: React.FC = () => { const { t } = useTranslation() const [phraseData, setPhraseData] = useState([]) const { agent } = useAdeyaAgent() + const route = useRoute() + const { backupType }: { backupType?: string } = route.params || {} const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window') @@ -157,7 +159,7 @@ const ExportWallet: React.FC = () => { title={'Continue'} accessibilityLabel={'Okay'} buttonType={ButtonType.Primary} - onPress={() => navigation.navigate(Screens.ExportWalletConfirmation, { phraseData })} + onPress={() => navigation.navigate(Screens.ExportWalletConfirmation, { phraseData, backupType })} /> diff --git a/app/screens/GoogleDriveSignIn.tsx b/app/screens/GoogleDriveSignIn.tsx new file mode 100644 index 00000000..d5196271 --- /dev/null +++ b/app/screens/GoogleDriveSignIn.tsx @@ -0,0 +1,60 @@ +import AsyncStorage from '@react-native-async-storage/async-storage' +import { GoogleSignin, GoogleSigninButton, statusCodes, User } from '@react-native-google-signin/google-signin' +import { useNavigation } from '@react-navigation/core' +import React, { useState } from 'react' +import { useTranslation } from 'react-i18next' +import { View, StyleSheet, Alert } from 'react-native' + +import { useAuth } from '../contexts/auth' +import { useTheme } from '../contexts/theme' +import { Screens } from '../types/navigators' + +const GoogleDriveSignIn: React.FC = () => { + const [, setUserInfo] = useState(null) + const { ColorPallet } = useTheme() + const navigation = useNavigation() + const { t } = useTranslation() + const { signIn } = useAuth() + const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: ColorPallet.brand.primaryBackground, + }, + }) + + const authenticateWithGoogle = async () => { + try { + await GoogleSignin.hasPlayServices() + const userInfo = await GoogleSignin.signIn() + setUserInfo(userInfo) + await AsyncStorage.setItem('userInfo', JSON.stringify(userInfo)) + signIn() + navigation.replace(Screens.ExportWallet, { backupType: 'google_drive' }) + } catch (error: any) { + if (error.code === statusCodes.SIGN_IN_CANCELLED) { + Alert.alert('Sign-In Cancelled', t('GoogleDrive.SignInCancelled')) + } else if (error.code === statusCodes.IN_PROGRESS) { + Alert.alert('Sign-In In Progress', t('GoogleDrive.SignInProgress')) + } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) { + Alert.alert('Play Services Not Available', t('GoogleDrive.PlayServicesNotAvailable')) + } else { + Alert.alert('Sign-In Error', t('GoogleDrive.SignInError')) + } + } + } + + return ( + + + + ) +} + +export default GoogleDriveSignIn diff --git a/app/screens/Settings.tsx b/app/screens/Settings.tsx index 1d644e2a..f959dff3 100644 --- a/app/screens/Settings.tsx +++ b/app/screens/Settings.tsx @@ -19,6 +19,7 @@ import Toast from 'react-native-toast-message' import Icon from 'react-native-vector-icons/MaterialIcons' import { ToastType } from '../components/toast/BaseToast' +import { useAuth } from '../contexts/auth' import { useConfiguration } from '../contexts/configuration' import { DispatchAction } from '../contexts/reducers/store' import { useStore } from '../contexts/store' @@ -46,6 +47,7 @@ const Settings: React.FC = ({ navigation }) => { const [enablePushNotifications, setEnablePushNotifications] = useState(false) const [pushNotificationCapable, setPushNotificationCapable] = useState(true) const [holderDid, setHolderDid] = useState('') + const { isSignedIn, signOut } = useAuth() const languages = [{ id: Locales.en, value: t('Language.English') }] @@ -208,7 +210,35 @@ const Settings: React.FC = ({ navigation }) => { onPress: () => navigation.navigate(Screens.ExportWallet as never), value: undefined, }, - ], + { + title: t('Backup.backup_google_drive'), + accessibilityLabel: t('Settings.GoogleDriveBackup'), + testID: testIdWithKey('BackupGoogleDrive'), + onPress: async () => { + if (isSignedIn) { + navigation.navigate(Screens.ExportWallet, { backupType: 'google_drive' }) + } else { + navigation.navigate(Screens.GoogleDriveSignIn as never) + } + }, + value: undefined, + }, + isSignedIn && { + title: t('GoogleDrive.SignOutGoogle'), + accessibilityLabel: t('GoogleDrive.SignOutGoogle'), + testID: testIdWithKey('SignOutGoogleAccount'), + onPress: async () => { + await signOut() + Toast.show({ + type: ToastType.Success, + text1: t('GoogleDrive.SignOutGoogleSuccess'), + position: 'bottom', + }) + navigation.navigate(Screens.Settings) + }, + value: undefined, + }, + ].filter(Boolean), }, { diff --git a/app/types/navigators.ts b/app/types/navigators.ts index 5d0844b7..80db3580 100644 --- a/app/types/navigators.ts +++ b/app/types/navigators.ts @@ -49,6 +49,7 @@ export enum Screens { DataRetention = 'Data Retention', Explore = 'Explore', OrganizationDetails = 'Organization Details', + GoogleDriveSignIn = 'Google Drive Sign In', } export enum Stacks { From 2fb8f30ff39a62ca2c0ef840aaa0d0299e89bf7b Mon Sep 17 00:00:00 2001 From: Piyush Upadhyay Date: Thu, 27 Jun 2024 16:22:03 +0530 Subject: [PATCH 4/6] upload backup file to google drive Signed-off-by: Piyush Upadhyay --- app/localization/en/index.ts | 2 + app/screens/ExportWalletConfirmation.tsx | 68 ++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/app/localization/en/index.ts b/app/localization/en/index.ts index 81e3c52b..fe32f576 100644 --- a/app/localization/en/index.ts +++ b/app/localization/en/index.ts @@ -720,6 +720,8 @@ const translation = { "SignInError": "An error occurred during sign-in", "SignOutGoogle": "Sign Out of Google Account", "SignOutGoogleSuccess": "Google Sign Out Successful", + "BackupFailed": "Backup failed to upload to Google Drive. Please try again later.", + "BackupSuccess": "Backup successfully uploaded to Google Drive.", }, } diff --git a/app/screens/ExportWalletConfirmation.tsx b/app/screens/ExportWalletConfirmation.tsx index f14a560a..e0cd768f 100644 --- a/app/screens/ExportWalletConfirmation.tsx +++ b/app/screens/ExportWalletConfirmation.tsx @@ -1,5 +1,7 @@ import { exportWallet as exportAdeyaWallet } from '@adeya/ssi' +import { GoogleSignin } from '@react-native-google-signin/google-signin' import { useNavigation, useRoute } from '@react-navigation/core' +import { GDrive, ListQueryBuilder, MimeTypes } from '@robinbobin/react-native-google-drive-api-wrapper' import shuffle from 'lodash.shuffle' import moment from 'moment' import React, { useEffect, useState } from 'react' @@ -171,11 +173,67 @@ function ExportWalletConfirmation() { await RNFS.unlink(zipUpDirectory) - if (Platform.OS === 'ios') { - await Share.share({ - title: 'Share backup zip file', - url: destinationZipPath, - }) + if (parms?.params?.backupType === 'google_drive') { + const gdrive = new GDrive() + gdrive.accessToken = (await GoogleSignin.getTokens()).accessToken + gdrive.fetchCoercesTypes = true + gdrive.fetchRejectsOnHttpErrors = true + gdrive.fetchTimeout = 15000 + + const zipFileData = await RNFS.readFile(destinationZipPath, 'base64') + try { + const { result } = await gdrive.files.createIfNotExists( + { + q: new ListQueryBuilder() + .e('name', 'ADEYA Wallet Backups') + .and() + .e('mimeType', MimeTypes.FOLDER) + .and() + .in('root', 'parents'), + }, + gdrive.files.newMetadataOnlyUploader().setRequestBody({ + name: 'ADEYA Wallet Backups', + mimeType: MimeTypes.FOLDER, + parents: ['root'], + }), + ) + + const response = await gdrive.files + .newMultipartUploader() + .setData(zipFileData, 'application/zip') + .setIsBase64(true) + .setRequestBody({ + name: zipFileName, + parents: [result.id], + }) + .execute() + + const folderData = await gdrive.files.getMetadata(result.id) + const fileData = await gdrive.files.getMetadata(response.id) + Toast.show({ + type: ToastType.Success, + text1: t('GoogleDrive.BackupSuccess'), + }) + setMatchPhrase(true) + navigation.navigate(Screens.Success, { + encryptedFileLocation: `Backup file uploaded successfully to Google Drive\n\nFolder: ${folderData.name}\n\nFile: ${fileData.name}`, + }) + return + } catch (e) { + Toast.show({ + type: ToastType.Error, + text1: t('GoogleDrive.BackupFailed'), + position: 'bottom', + }) + return + } + } else { + if (Platform.OS === 'ios') { + await Share.share({ + title: 'Share backup zip file', + url: destinationZipPath, + }) + } } Toast.show({ From 8e1febc423cba945ab50325e9114773972683e2c Mon Sep 17 00:00:00 2001 From: Piyush Upadhyay Date: Mon, 1 Jul 2024 19:11:59 +0530 Subject: [PATCH 5/6] improved variable names and removed signout toast Signed-off-by: Piyush Upadhyay --- app/contexts/auth.tsx | 34 +++++++++++++++---------------- app/screens/GoogleDriveSignIn.tsx | 10 ++++----- app/screens/Settings.tsx | 13 ++++-------- 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/app/contexts/auth.tsx b/app/contexts/auth.tsx index 29fd6253..c6abdfa9 100644 --- a/app/contexts/auth.tsx +++ b/app/contexts/auth.tsx @@ -31,38 +31,36 @@ export interface AuthContext { setPIN: (PIN: string) => Promise commitPIN: (useBiometry: boolean) => Promise isBiometricsActive: () => Promise - isSignedIn: boolean - signIn: () => Promise - signOut: () => Promise + isGoogleAccountSignedIn: boolean + googleSignIn: () => Promise + googleSignOut: () => Promise } export const AuthContext = createContext(null as unknown as AuthContext) export const AuthProvider: React.FC = ({ children }) => { const [walletSecret, setWalletSecret] = useState() - const [isSignedIn, setIsSignedIn] = useState(false) + const [isGoogleAccountSignedIn, setIsGoogleAccountSignedIn] = useState(false) const [, dispatch] = useStore() const { t } = useTranslation() useEffect(() => { - const checkSignInStatus = async () => { - const userInfo = await AsyncStorage.getItem('userInfo') - setIsSignedIn(userInfo !== null) + const checkGoogleSignInStatus = async () => { + const googleUserInfo = await AsyncStorage.getItem('googleUserInfo') + setIsGoogleAccountSignedIn(googleUserInfo !== null) } - checkSignInStatus() + checkGoogleSignInStatus() }, []) - const signIn = async (): Promise => { - // const userInfo = await GoogleSignin.signIn() - // await AsyncStorage.setItem('userInfo', JSON.stringify(userInfo)) - setIsSignedIn(true) + const googleSignIn = async (): Promise => { + setIsGoogleAccountSignedIn(true) } - const signOut = async (): Promise => { + const googleSignOut = async (): Promise => { try { await GoogleSignin.signOut() - await AsyncStorage.removeItem('userInfo') - setIsSignedIn(false) + await AsyncStorage.removeItem('googleUserInfo') + setIsGoogleAccountSignedIn(false) } catch (error) { // error message } @@ -158,9 +156,9 @@ export const AuthProvider: React.FC = ({ children }) => { commitPIN, setPIN, isBiometricsActive, - isSignedIn, - signIn, - signOut, + isGoogleAccountSignedIn, + googleSignIn, + googleSignOut, }}> {children} diff --git a/app/screens/GoogleDriveSignIn.tsx b/app/screens/GoogleDriveSignIn.tsx index d5196271..38b6f64a 100644 --- a/app/screens/GoogleDriveSignIn.tsx +++ b/app/screens/GoogleDriveSignIn.tsx @@ -14,7 +14,7 @@ const GoogleDriveSignIn: React.FC = () => { const { ColorPallet } = useTheme() const navigation = useNavigation() const { t } = useTranslation() - const { signIn } = useAuth() + const { googleSignIn } = useAuth() const styles = StyleSheet.create({ container: { flex: 1, @@ -27,10 +27,10 @@ const GoogleDriveSignIn: React.FC = () => { const authenticateWithGoogle = async () => { try { await GoogleSignin.hasPlayServices() - const userInfo = await GoogleSignin.signIn() - setUserInfo(userInfo) - await AsyncStorage.setItem('userInfo', JSON.stringify(userInfo)) - signIn() + const googleUserInfo = await GoogleSignin.signIn() + setUserInfo(googleUserInfo) + await AsyncStorage.setItem('googleUserInfo', JSON.stringify(googleUserInfo)) + googleSignIn() navigation.replace(Screens.ExportWallet, { backupType: 'google_drive' }) } catch (error: any) { if (error.code === statusCodes.SIGN_IN_CANCELLED) { diff --git a/app/screens/Settings.tsx b/app/screens/Settings.tsx index 716bf4bc..9abb9bd8 100644 --- a/app/screens/Settings.tsx +++ b/app/screens/Settings.tsx @@ -47,7 +47,7 @@ const Settings: React.FC = ({ navigation }) => { const [enablePushNotifications, setEnablePushNotifications] = useState(false) const [pushNotificationCapable, setPushNotificationCapable] = useState(true) const [holderDid, setHolderDid] = useState('') - const { isSignedIn, signOut } = useAuth() + const { isGoogleAccountSignedIn, googleSignOut } = useAuth() const languages = [{ id: Locales.en, value: t('Language.English') }] @@ -215,7 +215,7 @@ const Settings: React.FC = ({ navigation }) => { accessibilityLabel: t('Settings.GoogleDriveBackup'), testID: testIdWithKey('BackupGoogleDrive'), onPress: async () => { - if (isSignedIn) { + if (isGoogleAccountSignedIn) { navigation.navigate(Screens.ExportWallet, { backupType: 'google_drive' }) } else { navigation.navigate(Screens.GoogleDriveSignIn as never) @@ -223,17 +223,12 @@ const Settings: React.FC = ({ navigation }) => { }, value: undefined, }, - isSignedIn && { + isGoogleAccountSignedIn && { title: t('GoogleDrive.SignOutGoogle'), accessibilityLabel: t('GoogleDrive.SignOutGoogle'), testID: testIdWithKey('SignOutGoogleAccount'), onPress: async () => { - await signOut() - Toast.show({ - type: ToastType.Success, - text1: t('GoogleDrive.SignOutGoogleSuccess'), - position: 'bottom', - }) + await googleSignOut() navigation.navigate(Screens.Settings) }, value: undefined, From 16b8d4bcc3ed197d075f4505c950ba405ed79169 Mon Sep 17 00:00:00 2001 From: Piyush Upadhyay Date: Wed, 10 Jul 2024 15:57:21 +0530 Subject: [PATCH 6/6] restore wallet instructions Signed-off-by: Piyush Upadhyay --- app/localization/en/index.ts | 5 +++ app/screens/CreateWallet.tsx | 74 ++++++++++++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/app/localization/en/index.ts b/app/localization/en/index.ts index f5bc596d..9d8a226b 100644 --- a/app/localization/en/index.ts +++ b/app/localization/en/index.ts @@ -726,6 +726,11 @@ const translation = { "BackupFailed": "Backup failed to upload to Google Drive. Please try again later.", "BackupSuccess": "Backup successfully uploaded to Google Drive.", }, + "Restore": { + "RestoreWallet": "Restore Wallet", + "RestoreInstructions": "Note: To restore your wallet, you can use a backup from your cloud storage or local device. Please ensure that the Google Drive app is installed on your device and you are signed in.", + "RestoreInstructionsIOS": "If you can't see Google Drive in the file picker, open the Files app --> tap on the three dots at the top --> select 'Edit' --> enable Google Drive.", + }, } export default translation diff --git a/app/screens/CreateWallet.tsx b/app/screens/CreateWallet.tsx index 24874dc8..73c46bdd 100644 --- a/app/screens/CreateWallet.tsx +++ b/app/screens/CreateWallet.tsx @@ -1,6 +1,8 @@ import { useNavigation } from '@react-navigation/core' -import React from 'react' -import { View, StyleSheet, Text } from 'react-native' +import React, { useState } from 'react' +import { useTranslation } from 'react-i18next' +import { View, StyleSheet, Text, Platform, Modal, TouchableOpacity } from 'react-native' +import Icon from 'react-native-vector-icons/FontAwesome' import Button, { ButtonType } from '../components/buttons/Button' import { useTheme } from '../contexts/theme' @@ -9,6 +11,18 @@ import { Screens } from '../types/navigators' const CreateWallet: React.FC = () => { const { TextTheme, ColorPallet } = useTheme() const navigation = useNavigation() + const { t } = useTranslation() + const [isModalVisible, setModalVisible] = useState(false) + + const toggleModal = () => { + setModalVisible(!isModalVisible) + } + + const proceedWithRestore = () => { + toggleModal() + navigation.navigate(Screens.ImportWalletVerify as never) + } + const styles = StyleSheet.create({ container: { flex: 1, @@ -21,6 +35,11 @@ const CreateWallet: React.FC = () => { color: ColorPallet.brand.primary, marginTop: 20, }, + instructionsText: { + fontSize: 16, + color: ColorPallet.brand.primary, + marginVertical: 10, + }, walletButtonView: { marginTop: 'auto', margin: 20, @@ -28,6 +47,29 @@ const CreateWallet: React.FC = () => { restoreWalletView: { marginTop: 20, }, + modalOverlay: { + flex: 1, + backgroundColor: 'rgba(0, 0, 0, 0.5)', + justifyContent: 'center', + alignItems: 'center', + padding: 20, + }, + modalHeader: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + marginBottom: 15, + }, + modalContent: { + backgroundColor: ColorPallet.brand.modalSecondary, + padding: 22, + borderRadius: 4, + }, + modalTitle: { + fontSize: 24, + color: ColorPallet.brand.primary, + fontWeight: 'bold', + }, }) return ( @@ -43,11 +85,37 @@ const CreateWallet: React.FC = () => {