You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
//TODO: Probably can never know that these are the situation - can't tell the difference between user typing the wrong password and can't try the remote file password anyway until the service password is correct. Maybe delete these enum values?
38
-
//RemoteUserAndFileDiffers,
39
-
//AllThreeAreDifferent
40
-
}
41
-
42
33
classVaultCubitextendsCubit<VaultState> {
43
34
finalRemoteVaultRepository _remoteVaultRepo;
44
35
finalLocalVaultRepository _localVaultRepo;
@@ -574,6 +565,18 @@ class VaultCubit extends Cubit<VaultState> {
574
565
l.i('refresh called during an ongoing upload. Will not refresh now.');
575
566
return;
576
567
}
568
+
if (s isVaultRefreshing) {
569
+
l.i('refresh called during an ongoing refresh operation. Will not start a new refresh now.');
570
+
return;
571
+
}
572
+
if (s isVaultRefreshCredentialsRequired&& recovery ==PasswordMismatchRecoverySituation.None) {
573
+
l.i('refresh called during an ongoing refresh credentials repair operation. Will not refresh now.');
574
+
return;
575
+
}
576
+
if (s isVaultUploadCredentialsRequired&& recovery ==PasswordMismatchRecoverySituation.None) {
577
+
l.i('refresh called during an ongoing upload credentials repair operation. Will not refresh now.');
578
+
return;
579
+
}
577
580
if (s isVaultChangingPassword) {
578
581
l.i('refresh called during a password change. Will not refresh now.');
579
582
return;
@@ -666,15 +669,27 @@ class VaultCubit extends Cubit<VaultState> {
//TODO: else... probably already handled by next step? need to check we use the updatedlocalfile as our local one since that now has the correct kdbx password.
684
+
} else {
685
+
if (tempLockedFile ==null) {
686
+
l.d("Latest remote file not changed so didn't download it");
// RemoteFileDiffers only time and safe time to save the credentials? we are saying whatever creds worked to open the remote file is what we will save as the credentials needed to open the local file.
755
+
// updatedLocalFile must be null if we are in remotefilediffers mode
736
756
if (recovery ==PasswordMismatchRecoverySituation.RemoteFileDiffers&& successfulCredentials !=null) {
737
757
l.d('Updating QU with newly successful KDBX password');
738
758
final requireFullPasswordPeriod =
@@ -747,7 +767,7 @@ class VaultCubit extends Cubit<VaultState> {
@@ -774,7 +794,7 @@ class VaultCubit extends Cubit<VaultState> {
774
794
l.d('refresh called during an import. Will not refresh now.');
775
795
return;
776
796
}
777
-
throwException('Vault not loaded when refresh called');
797
+
l.w('Vault not loaded when refresh called');
778
798
}
779
799
}
780
800
@@ -1610,8 +1630,10 @@ class VaultCubit extends Cubit<VaultState> {
1610
1630
1611
1631
voidstartEmailChange() {
1612
1632
if (currentVaultFile ==null|| (!currentVaultFile!.files.current.isDirty && _entryCubit.state is!EntryLoaded)) {
1613
-
//TODO: test if just signing out triggers the request to sign in again automatically or if it is to do with the change to the account cubit
1614
-
// _accountCubit.startEmailChange();
1633
+
//TODO: test if just signing out triggers the request to sign in again automatically or if it is
1634
+
// to do with the change to the account cubit
1635
+
// result: Yes, signout results in immediate re-signin so cubit account request can never work. need to do something different to sign-out. maybe forget the user or sign out the account level user too? would be good to remeember their email address though since really we only want to sign them out from the vault, not their user account.
1636
+
_accountCubit.startEmailChange();
1615
1637
signout();
1616
1638
} else {
1617
1639
emitError('You must save your changes first!', toast:true);
//TODO: Probably can never know that these are the situation - can't tell the difference between user typing the wrong password and can't try the remote file password anyway until the service password is correct. Maybe delete these enum values?
7
+
//RemoteUserAndFileDiffers,
8
+
//AllThreeAreDifferent
9
+
}
10
+
11
+
/*
12
+
13
+
We try to automatically resolve all mismatched password situations here.
14
+
15
+
There are 3 current passwords we need to align - they generally always are aligned but crashes or bugs, particularly during a password change procedure, can cause them to get out of sync.
16
+
17
+
The 3 passwords are:
18
+
Local KDBX file - the remoteMargeTarget unless current is newer
19
+
Remote KDBX file
20
+
Remote user authentication password
21
+
22
+
We'll need to align on the remote authentication password so that the user doesn't get stuck in a constant battle between conflicting local passwords on multiple devices.
23
+
24
+
Slightly old tokens being used to upload modified RK could result in state 1 or 2.
25
+
26
+
p1 p2 and p3 have no specific temporal ordering. Depending on how we ended up in one of these states, any of those could be considered "newest".
27
+
28
+
Thus the possible failure modes are:
29
+
30
+
1) RemoteUserDiffers
31
+
32
+
LK = p1
33
+
RK = p1
34
+
RU = p2
35
+
36
+
Symptom:
37
+
User will be unable to download or upload the RK file
38
+
39
+
Solution:
40
+
User provides an override password which we use for authentication.
41
+
Need to use non-override password to unlock RK. But we don't know in advance if we are in this state or 3. So we assume 3 and actually progress towards state 2. Ideally we resolve in the same step by just trying again with p1 but in worst case user could enter a password again.
42
+
If RK is newer, download it, change its password to p2, change LK password to p2, merge it, store result as LK and upload as RK.
43
+
If RK is not newer, change LK password to p2, store result as LK and upload as RK.
44
+
45
+
46
+
2) RemoteFileDiffers
47
+
48
+
LK = p1
49
+
RK = p2
50
+
RU = p1
51
+
52
+
Symptom:
53
+
User will be unable to unlock the RK file while merging for upload or downloading for refresh/syncing.
54
+
55
+
Solution:
56
+
User provides an override password which we use for unlocking the RK.
57
+
Need to use non-override password to download/upload RK. So we need to know that RU worked when getting p2 from the user.
58
+
If RK is newer, download it, change its password to p1, merge it, store result as LK and upload as RK.
59
+
If RK is not newer, upload LK as RK.
60
+
61
+
62
+
3) RemoteUserAndFileDiffers
63
+
64
+
LK = p1
65
+
RK = p2
66
+
RU = p2
67
+
68
+
Symptom:
69
+
User will be unable to download or modify the RK file, nor unlock it using their local password
70
+
71
+
Solution:
72
+
User provides an override password which we use for authentication and to unlock RK.
73
+
If RK is newer, download it, change LK password to p2, merge it, store result as LK and upload as RK.
74
+
If RK is not newer, change LK password to p2, store result as LK and upload as RK.
75
+
76
+
4) AllThreeAreDifferent
77
+
78
+
LK = p1
79
+
RK = p2
80
+
RU = p3
81
+
82
+
Solution:
83
+
Ignore. We hope that existing support for other situations will allow the user to muddle through to a resolution in multiple steps.
84
+
85
+
86
+
87
+
Generally, we will need to track whether it was the RK or RU that failed. That lets us determine between states 1,2 and 3+4. We know we are in 3+4 if trying to resolve 3 fails at either the access request or RK unlocking stage. Once the user enters p3, we can change LK with that password and thus effectively reduce the problem to state 1 (which user can then resolve by entering what was p2 in this scenario). We won't implement all of this edge case but expect at least that forcibly killing the app at the right time will allow the user to recover.
@@ -22,6 +24,7 @@ class _AccountEmailChangeWidgetState extends State<AccountEmailChangeWidget> {
22
24
// We always sign the user out. Might be nice to send them back to their Vault if that's where they came from (i.e. they have a validated and active account) but might be hard to do securely so will ignore that edge case initially.
23
25
final accountCubit =BlocProvider.of<AccountCubit>(context);
0 commit comments