diff --git a/android/fastlane/metadata/android/en-US/changelogs/124.txt b/android/fastlane/metadata/android/en-US/changelogs/124.txt new file mode 100644 index 0000000000..2f9351fee7 --- /dev/null +++ b/android/fastlane/metadata/android/en-US/changelogs/124.txt @@ -0,0 +1,2 @@ +- Fixes an issue where the tutorial is incorrectly displayed for users with existing public drives when logging in via ArConnect. +- Fixes a login failure issue that occurred when switching wallets on the login page. \ No newline at end of file diff --git a/lib/authentication/ardrive_auth.dart b/lib/authentication/ardrive_auth.dart index 4c58f6cfcc..fedcd46d62 100644 --- a/lib/authentication/ardrive_auth.dart +++ b/lib/authentication/ardrive_auth.dart @@ -85,9 +85,6 @@ class ArDriveAuthImpl implements ArDriveAuth { User? _currentUser; - @visibleForTesting - String? firstPrivateDriveTxId; - // getters and setters @override User get currentUser { @@ -233,7 +230,6 @@ class ArDriveAuthImpl implements ArDriveAuth { await _secureKeyValueStore.remove('password'); await _secureKeyValueStore.remove('biometricEnabled'); currentUser = null; - firstPrivateDriveTxId = null; await _disconnectFromArConnect(); _userStreamController.add(null); } @@ -339,12 +335,10 @@ class ArDriveAuthImpl implements ArDriveAuth { } Future _getFirstPrivateDriveTxId(Wallet wallet) async { - firstPrivateDriveTxId ??= await _arweave.getFirstPrivateDriveTxId( + return _arweave.getFirstPrivateDriveTxId( wallet, maxRetries: profileQueryMaxRetries, ); - - return firstPrivateDriveTxId; } @override diff --git a/lib/authentication/login/blocs/login_bloc.dart b/lib/authentication/login/blocs/login_bloc.dart index f2e3a3ed1c..9ed6f13e53 100644 --- a/lib/authentication/login/blocs/login_bloc.dart +++ b/lib/authentication/login/blocs/login_bloc.dart @@ -480,8 +480,14 @@ class LoginBloc extends Bloc { if (await _arDriveAuth.userHasPassword(wallet)) { emit(PromptPassword(wallet: wallet, showWalletCreated: false)); } else { - emit(CreateNewPassword( - wallet: wallet, showTutorials: true, showWalletCreated: false)); + final hasDrives = await _arDriveAuth.isExistingUser(wallet); + emit( + CreateNewPassword( + wallet: wallet, + showTutorials: !hasDrives, + showWalletCreated: false, + ), + ); } } catch (e) { emit(previousState); diff --git a/pubspec.yaml b/pubspec.yaml index 4561c2f103..e04b6f85bb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: Secure, permanent storage publish_to: 'none' -version: 2.42.0 +version: 2.42.1 environment: sdk: '>=3.2.0 <4.0.0' diff --git a/test/authentication/ardrive_auth_test.dart b/test/authentication/ardrive_auth_test.dart index bad988b10f..00716e5ecf 100644 --- a/test/authentication/ardrive_auth_test.dart +++ b/test/authentication/ardrive_auth_test.dart @@ -552,7 +552,6 @@ void main() { expect(() => arDriveAuth.currentUser, throwsA(isA())); - expect(arDriveAuth.firstPrivateDriveTxId, isNull); verify(() => mockSecureKeyValueStore.remove('password')).called(1); verify(() => mockSecureKeyValueStore.remove('biometricEnabled')) .called(1); @@ -640,7 +639,6 @@ void main() { await arDriveAuth.logout(); - expect(arDriveAuth.firstPrivateDriveTxId, isNull); expect(() => arDriveAuth.currentUser, throwsA(isA())); verify(() => mockSecureKeyValueStore.remove('password')).called(1); @@ -751,86 +749,6 @@ void main() { await arDriveAuth.logout(); }); }); - group('getFirstPrivateDriveTxId method', () { - final loggedUser = User( - password: 'password', - wallet: wallet, - walletAddress: 'walletAddress', - walletBalance: BigInt.one, - cipherKey: SecretKey([]), - profileType: ProfileType.json, - ); - - /// For this test we'll call the same method twice to validate if the - /// getFirstPrivateDriveTxId is called only once - - test( - 'should call getFirstPrivateDriveTxId only once when has private drives and login with sucess. ', - () async { - // arrange - when(() => mockArweaveService.getFirstPrivateDriveTxId( - wallet, - maxRetries: any(named: 'maxRetries'), - )).thenAnswer((_) async => 'some_id'); - - when(() => mockBiometricAuthentication.isEnabled()) - .thenAnswer((_) async => false); - - when( - () => mockArDriveCrypto.deriveDriveKey( - wallet, - any(), - any(), - ), - ).thenAnswer((invocation) => Future.value(SecretKey([]))); - - when(() => mockUserRepository.hasUser()) - .thenAnswer((invocation) => Future.value(true)); - - when(() => mockArweaveService.getLatestDriveEntityWithId(any(), - driveKey: any(named: 'driveKey'), - maxRetries: any(named: 'maxRetries'), - driveOwner: any(named: 'driveOwner'))) - .thenAnswer((invocation) => Future.value(DriveEntity( - id: 'some_id', - rootFolderId: 'some_id', - ))); - - when(() => mockUserRepository.deleteUser()) - .thenAnswer((invocation) async {}); - - when(() => mockUserRepository.saveUser( - 'password', ProfileType.json, wallet)) - .thenAnswer((invocation) => Future.value(null)); - - when(() => mockUserRepository.getUser('password')) - .thenAnswer((invocation) async => loggedUser); - - await arDriveAuth.login(wallet, 'password', ProfileType.json); - await arDriveAuth.login(wallet, 'password', ProfileType.json); - - verify( - () => mockArweaveService.getFirstPrivateDriveTxId( - wallet, - maxRetries: any(named: 'maxRetries'), - ), - ).called(1); - }); - - test( - 'should call getFirstPrivateDriveTxId only once when has private drives and login with sucess. ', - () async { - when(() => mockArweaveService.getFirstPrivateDriveTxId(wallet, - maxRetries: any(named: 'maxRetries'))) - .thenAnswer((_) async => 'some_id'); - - await arDriveAuth.userHasPassword(wallet); - await arDriveAuth.userHasPassword(wallet); - - verify(() => mockArweaveService.getFirstPrivateDriveTxId(wallet, - maxRetries: any(named: 'maxRetries'))).called(1); - }); - }); }); group('getWalletAddress method', () { diff --git a/test/authentication/login/blocs/login_bloc_test.dart b/test/authentication/login/blocs/login_bloc_test.dart index 4b7906c53b..6ae91c5645 100644 --- a/test/authentication/login/blocs/login_bloc_test.dart +++ b/test/authentication/login/blocs/login_bloc_test.dart @@ -655,7 +655,40 @@ void main() { .thenAnswer((invocation) => Future.value(true)); when(() => mockArConnectService.getWalletAddress()) .thenAnswer((invocation) => Future.value('walletAddress')); - // new user + // new user but has public drives + when(() => mockArDriveAuth.isExistingUser(any())) + .thenAnswer((invocation) => Future.value(true)); + when(() => mockArDriveAuth.userHasPassword(any())) + .thenAnswer((invocation) => Future.value(false)); + }, + act: (bloc) async { + bloc.add(const AddWalletFromArConnect()); + }, + expect: () => [ + LoginLoading(), + predicate((cnp) { + return cnp.showWalletCreated == false && + cnp.mnemonic == null && + cnp.showTutorials == false; + }) + ], + ); + + blocTest( + 'should emit a state to create new password when user never logged on ardrive and show tutorials if user has no drives', + build: () { + return createBloc(); + }, + setUp: () { + when(() => mockArConnectService.connect()) + .thenAnswer((invocation) => Future.value(null)); + when(() => mockArConnectService.checkPermissions()) + .thenAnswer((invocation) => Future.value(true)); + when(() => mockArConnectService.getWalletAddress()) + .thenAnswer((invocation) => Future.value('walletAddress')); + // new user and no drives + when(() => mockArDriveAuth.isExistingUser(any())) + .thenAnswer((invocation) => Future.value(false)); when(() => mockArDriveAuth.userHasPassword(any())) .thenAnswer((invocation) => Future.value(false)); },