Skip to content

Commit

Permalink
Merge pull request #1384 from ardriveapp/PE-4477
Browse files Browse the repository at this point in the history
PE-4477: ArDrive logout issue when switching ArConnect wallets after seed-phrase/json login
  • Loading branch information
matibat authored Sep 28, 2023
2 parents 9f41b9b + b48646f commit aa8e678
Show file tree
Hide file tree
Showing 13 changed files with 98 additions and 55 deletions.
29 changes: 20 additions & 9 deletions lib/app_shell.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:ardrive/components/profile_card.dart';
import 'package:ardrive/components/side_bar.dart';
import 'package:ardrive/pages/drive_detail/components/hover_widget.dart';
import 'package:ardrive/utils/html/html_util.dart';
import 'package:ardrive/utils/logger/logger.dart';
import 'package:ardrive/utils/size_constants.dart';
import 'package:ardrive_ui/ardrive_ui.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -32,16 +33,26 @@ class AppShellState extends State<AppShell> {
bool _showWalletSwitchDialog = true;
@override
Widget build(BuildContext context) => BlocBuilder<DrivesCubit, DrivesState>(
builder: (context, state) {
builder: (context, _) {
onArConnectWalletSwitch(() {
if (_showWalletSwitchDialog) {
showDialog(
context: context,
builder: (context) => const WalletSwitchDialog(),
);
}
//Used to prevent the dialog being shown multiple times.
_showWalletSwitchDialog = false;
context
.read<ProfileCubit>()
.isCurrentProfileArConnect()
.then((isCurrentProfileArConnect) {
if (_showWalletSwitchDialog) {
if (isCurrentProfileArConnect) {
showDialog(
context: context,
builder: (context) => const WalletSwitchDialog(),
);
} else {
logger.d('Wallet switch detected while not logged in'
' to ArConnect. Ignoring.');
}
}
//Used to prevent the dialog being shown multiple times.
_showWalletSwitchDialog = false;
});
});

Widget buildPage(scaffold) => Material(
Expand Down
29 changes: 15 additions & 14 deletions lib/authentication/ardrive_auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ abstract class ArDriveAuth {
Future<User> unlockWithBiometrics({required String localizedReason});
Future<User> unlockUser({required String password});
Future<void> logout();
User? get currentUser;
User get currentUser;
Stream<User?> onAuthStateChanged();
Future<bool> isBiometricsEnabled();

Expand Down Expand Up @@ -216,32 +216,33 @@ class ArDriveAuthImpl implements ArDriveAuth {

try {
if (_currentUser != null) {
if (currentUser.profileType == ProfileType.arConnect) {
try {
await _arConnectService.disconnect();
} catch (e) {
logger.e('Failed to disconnect from ArConnect', e);
}
}

_secureKeyValueStore.remove('password');
_secureKeyValueStore.remove('biometricEnabled');

await _secureKeyValueStore.remove('password');
await _secureKeyValueStore.remove('biometricEnabled');
currentUser = null;
firstPrivateDriveTxId = null;

await _disconnectFromArConnect();
_userStreamController.add(null);
}

await _databaseHelpers.deleteAllTables();

(await _metadataCache).clear();
} catch (e) {
logger.e('Failed to logout user', e);
throw AuthenticationFailedException('Failed to logout user');
}
}

Future<void> _disconnectFromArConnect() async {
final hasArConnectPermissions = await _arConnectService.checkPermissions();
if (hasArConnectPermissions) {
try {
await _arConnectService.disconnect();
} catch (e) {
logger.e('Failed to disconnect from ArConnect', e);
}
}
}

@override
Future<bool> isBiometricsEnabled() {
return _biometricAuthentication.isEnabled();
Expand Down
58 changes: 41 additions & 17 deletions lib/authentication/login/blocs/login_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
}

Future<void> _handleUnlockUserWithBiometricsEvent(
UnLockWithBiometrics event, Emitter<LoginState> emit) async {
UnLockWithBiometrics event,
Emitter<LoginState> emit,
) async {
final previousState = state;

try {
Expand Down Expand Up @@ -107,7 +109,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
}

Future<void> _handleAddWalletFileEvent(
AddWalletFile event, Emitter<LoginState> emit) async {
AddWalletFile event,
Emitter<LoginState> emit,
) async {
final previousState = state;

try {
Expand All @@ -130,7 +134,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
}

Future<void> _handleLoginWithPasswordEvent(
LoginWithPassword event, Emitter<LoginState> emit) async {
LoginWithPassword event,
Emitter<LoginState> emit,
) async {
final previousState = state;

try {
Expand All @@ -150,7 +156,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
}

Future<void> _handleCheckIfUserIsLoggedInEvent(
CheckIfUserIsLoggedIn event, Emitter<LoginState> emit) async {
CheckIfUserIsLoggedIn event,
Emitter<LoginState> emit,
) async {
emit(LoginLoading());

if (await _arDriveAuth.isUserLoggedIn()) {
Expand All @@ -172,7 +180,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
}

Future<void> _handleUnlockUserWithPasswordEvent(
UnlockUserWithPassword event, Emitter<LoginState> emit) async {
UnlockUserWithPassword event,
Emitter<LoginState> emit,
) async {
final previousState = state;

emit(LoginLoading());
Expand All @@ -192,7 +202,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
}

Future<void> _handleCreatePasswordEvent(
CreatePassword event, Emitter<LoginState> emit) async {
CreatePassword event,
Emitter<LoginState> emit,
) async {
final previousState = state;

emit(LoginLoading());
Expand All @@ -212,7 +224,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
}

Future<void> _handleAddWalletFromArConnectEvent(
AddWalletFromArConnect event, Emitter<LoginState> emit) async {
AddWalletFromArConnect event,
Emitter<LoginState> emit,
) async {
final previousState = state;

try {
Expand Down Expand Up @@ -260,10 +274,6 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
await _arDriveAuth.logout();
}

if (_isArConnectWallet()) {
await _arConnectService.disconnect();
}

emit(LoginInitial(_arConnectService.isExtensionPresent()));
}

Expand Down Expand Up @@ -312,7 +322,13 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
return;
}

onArConnectWalletSwitch(() {
onArConnectWalletSwitch(() async {
final isUserLoggedIng = await _arDriveAuth.isUserLoggedIn();
if (isUserLoggedIng && !_isArConnectWallet()) {
logger.d('Wallet switch detected. Is current profile ArConnect: false');
return;
}

if (ignoreNextWaletSwitch) {
ignoreNextWaletSwitch = false;
return;
Expand All @@ -322,7 +338,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
// ignore: invalid_use_of_visible_for_testing_member
emit(const LoginFailure(WalletMismatchException()));

_arDriveAuth.logout();
await _arDriveAuth.logout();

// ignore: invalid_use_of_visible_for_testing_member
emit(const LoginInitial(true));
Expand All @@ -343,7 +359,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
}

Future<void> _handleEnterSeedPhrase(
EnterSeedPhrase event, Emitter<LoginState> emit) async {
EnterSeedPhrase event,
Emitter<LoginState> emit,
) async {
emit(LoginEnterSeedPhrase());
}

Expand All @@ -358,7 +376,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
}

Future<void> _handleAddWalletFromCompleterEvent(
AddWalletFromCompleter event, Emitter<LoginState> emit) async {
AddWalletFromCompleter event,
Emitter<LoginState> emit,
) async {
profileType = ProfileType.json;

Completer<Wallet> completer = event.walletCompleter;
Expand All @@ -380,14 +400,18 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
}

Future<void> _handleCreateNewWalletEvent(
CreateNewWallet event, Emitter<LoginState> emit) async {
CreateNewWallet event,
Emitter<LoginState> emit,
) async {
profileType = ProfileType.json;
final mnemonic = bip39.generateMnemonic();
emit(LoginCreateNewWallet(mnemonic));
}

Future<void> _handleCompleteWalletGenerationEvent(
CompleteWalletGeneration event, Emitter<LoginState> emit) async {
CompleteWalletGeneration event,
Emitter<LoginState> emit,
) async {
final previousState = state;
final wallet = event.wallet;

Expand Down
2 changes: 1 addition & 1 deletion lib/blocs/profile_add/profile_add_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class ProfileAddCubit extends Cubit<ProfileAddState> {
return arconnect.isExtensionPresent();
}

ProfileType? getProfileType() => _profileType;
ProfileType getProfileType() => _profileType;

Future<void> promptForWallet() async {
if (_profileType == ProfileType.arConnect) {
Expand Down
10 changes: 5 additions & 5 deletions lib/blocs/upload/upload_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ class UploadCubit extends Cubit<UploadState> {
try {
final uploadPreparation = await _arDriveUploadManager.prepareUpload(
params: UploadParams(
user: _auth.currentUser!,
user: _auth.currentUser,
files: files,
targetFolder: _targetFolder,
targetDrive: _targetDrive,
Expand Down Expand Up @@ -351,7 +351,7 @@ class UploadCubit extends Cubit<UploadState> {
'UploadPlan For AR: ${uploadPreparation.uploadPaymentInfo.arCostEstimate.toString()}\n'
'UploadPlan For Turbo: ${uploadPreparation.uploadPlansPreparation.uploadPlanForTurbo.toString()}\n'
'Turbo Balance: ${uploadPreparation.uploadPaymentInfo.turboBalance}\n'
'AR Balance: ${_auth.currentUser!.walletBalance}\n'
'AR Balance: ${_auth.currentUser.walletBalance}\n'
'Is Turbo Upload Possible: ${paymentInfo.isUploadEligibleToTurbo}\n'
'Is Zero Balance: $isTurboZeroBalance\n',
);
Expand Down Expand Up @@ -396,7 +396,7 @@ class UploadCubit extends Cubit<UploadState> {
costEstimateTurbo: paymentInfo.turboCostEstimate,
credits: literalBalance,
arBalance:
convertCreditsToLiteralString(_auth.currentUser!.walletBalance),
convertCreditsToLiteralString(_auth.currentUser.walletBalance),
uploadIsPublic: _targetDrive.isPublic,
sufficientArBalance:
profile.walletBalance >= paymentInfo.arCostEstimate.totalCost,
Expand Down Expand Up @@ -530,7 +530,7 @@ class UploadCubit extends Cubit<UploadState> {
}

ArDriveUploader _getUploader() {
final wallet = _auth.currentUser!.wallet;
final wallet = _auth.currentUser.wallet;

final turboUploader = TurboUploader(_turbo, wallet);
final arweaveUploader = ArweaveBundleUploader(_arweave.client);
Expand Down Expand Up @@ -558,7 +558,7 @@ class UploadCubit extends Cubit<UploadState> {
arweaveService: _arweave,
turboUploadService: _turbo,
pstService: _pst,
wallet: _auth.currentUser!.wallet,
wallet: _auth.currentUser.wallet,
isArConnect: await _profileCubit.isCurrentProfileArConnect(),
useTurbo: _uploadMethod == UploadMethod.turbo,
);
Expand Down
2 changes: 1 addition & 1 deletion lib/components/upload_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Future<void> promptToUpload(
),
turboUploadCostCalculator: TurboUploadCostCalculator(
priceEstimator: TurboPriceEstimator(
wallet: context.read<ArDriveAuth>().currentUser!.wallet,
wallet: context.read<ArDriveAuth>().currentUser.wallet,
costCalculator: TurboCostCalculator(
paymentService: context.read<PaymentService>(),
),
Expand Down
2 changes: 1 addition & 1 deletion lib/core/upload/uploader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ class UploadPaymentEvaluator {
/// If we can't get the balance, turbo won't be available
try {
turboBalance =
await _turboBalanceRetriever.getBalance(_auth.currentUser!.wallet);
await _turboBalanceRetriever.getBalance(_auth.currentUser.wallet);

logger.i('Turbo balance: $turboBalance');
} catch (e, stacktrace) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class DriveFileDropZoneState extends State<DriveFileDropZone> {
),
turboUploadCostCalculator: TurboUploadCostCalculator(
priceEstimator: TurboPriceEstimator(
wallet: context.read<ArDriveAuth>().currentUser!.wallet,
wallet: context.read<ArDriveAuth>().currentUser.wallet,
costCalculator: TurboCostCalculator(
paymentService: context.read<PaymentService>(),
),
Expand Down
4 changes: 2 additions & 2 deletions lib/turbo/topup/views/topup_modal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ void showTurboModal(BuildContext context, {Function()? onSuccess}) {
);

final priceEstimator = TurboPriceEstimator(
wallet: context.read<ArDriveAuth>().currentUser!.wallet,
wallet: context.read<ArDriveAuth>().currentUser.wallet,
paymentService: context.read<PaymentService>(),
costCalculator: costCalculator,
);
Expand All @@ -52,7 +52,7 @@ void showTurboModal(BuildContext context, {Function()? onSuccess}) {
balanceRetriever: balanceRetriever,
priceEstimator: priceEstimator,
paymentProvider: turboPaymentProvider,
wallet: context.read<ArDriveAuth>().currentUser!.wallet,
wallet: context.read<ArDriveAuth>().currentUser.wallet,
supportedCountriesRetriever: turboSupportedCountriesRetriever,
);

Expand Down
2 changes: 1 addition & 1 deletion lib/user/download_wallet/bloc/download_wallet_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class DownloadWalletBloc
return;
}
try {
final wallet = _ardriveAuth.currentUser!.wallet;
final wallet = _ardriveAuth.currentUser.wallet;

await _ardriveIOUtils.downloadWalletAsJsonFile(
wallet: wallet,
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/user_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:ardrive/user/user.dart';
bool isDriveOwner(ArDriveAuth auth, String driveOwner) {
User user;
try {
user = auth.currentUser!;
user = auth.currentUser;
} catch (e) {
return false;
}
Expand Down
9 changes: 8 additions & 1 deletion test/authentication/ardrive_auth_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ void main() {
id: 'some_id',
rootFolderId: 'some_id',
));

when(() => mockArConnectService.checkPermissions()).thenAnswer(
(invocation) => Future.value(true),
);
when(() => mockArConnectService.disconnect()).thenAnswer(
(invocation) => Future.value(null),
);
});

// test `ArDriveAuth`
Expand Down Expand Up @@ -643,7 +650,7 @@ void main() {
when(() => mockArweaveService.getFirstPrivateDriveTxId(wallet,
maxRetries: any(named: 'maxRetries')))
.thenAnswer((_) async => 'some_id');
// mock cripto derive drive key
// mock crypto derive drive key
when(
() => mockArDriveCrypto.deriveDriveKey(
wallet,
Expand Down
Loading

0 comments on commit aa8e678

Please sign in to comment.