Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Handle case account data arrives before put request finishes #2032

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 8 additions & 14 deletions lib/encryption/ssss.dart
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ class SSSS {
client.userID!,
EventTypes.SecretStorageDefaultKey,
SecretStorageDefaultKeyContent(key: keyId).toJson(),
waitForSync: true,
);
}

Expand Down Expand Up @@ -270,13 +271,9 @@ class SSSS {
client.userID!,
accountDataTypeKeyId,
content.toJson(),
waitForSync: true,
);

while (!client.accountData.containsKey(accountDataTypeKeyId)) {
Logs().v('Waiting accountData to have $accountDataTypeKeyId');
await client.oneShotSync();
}

final key = open(keyId);
await key.setPrivateKey(privateKey);
return key;
Expand Down Expand Up @@ -396,7 +393,12 @@ class SSSS {
'mac': encrypted.mac,
};
// store the thing in your account data
await client.setAccountData(client.userID!, type, content);
await client.setAccountData(
client.userID!,
type,
content,
waitForSync: true,
);
final db = client.database;
if (cacheTypes.contains(type) && db != null) {
// cache the thing
Expand Down Expand Up @@ -789,14 +791,6 @@ class OpenSSSS {
throw Exception('SSSS not unlocked');
}
await ssss.store(type, secret, keyId, privateKey, add: add);
while (!ssss.client.accountData.containsKey(type) ||
!(ssss.client.accountData[type]!.content
.tryGetMap<String, Object?>('encrypted')!
.containsKey(keyId)) ||
await getStored(type) != secret) {
Logs().d('Wait for secret of $type to match in accountdata');
await ssss.client.oneShotSync();
}
}

Future<void> validateAndStripOtherKeys(String type, String secret) async {
Expand Down
16 changes: 5 additions & 11 deletions lib/encryption/utils/bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,6 @@ class Bootstrap {
// alright, we re-encrypted all the secrets. We delete the dead weight only *after* we set our key to the default key
}
await encryption.ssss.setDefaultKeyId(newSsssKey!.keyId);
while (encryption.ssss.defaultKeyId != newSsssKey!.keyId) {
Logs().v(
'Waiting accountData to have the correct m.secret_storage.default_key',
);
await client.oneShotSync();
}
if (oldSsssKeys != null) {
for (final entry in secretMap!.entries) {
Logs().v('Validate and stripe other keys ${entry.key}...');
Expand Down Expand Up @@ -485,12 +479,12 @@ class Bootstrap {
);
Logs().v('Device signing keys have been uploaded.');
// aaaand set the SSSS secrets
if (masterKey != null) {
while (!(masterKey.publicKey != null &&
client.userDeviceKeys[client.userID]?.masterKey?.ed25519Key ==
masterKey.publicKey)) {
if (masterKey?.publicKey != null) {
while (!(client.userDeviceKeys[client.userID]?.masterKey?.ed25519Key ==
masterKey?.publicKey)) {
Logs().v('Waiting for master to be created');
await client.oneShotSync();
await client.onSyncStatus.stream
.firstWhere((status) => status.status == SyncStatus.finished);
}
}
if (newSsssKey != null) {
Expand Down
19 changes: 19 additions & 0 deletions lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3677,6 +3677,25 @@ class Client extends MatrixApi {
thirdPartySigned: thirdPartySigned,
);

@override
Future<void> setAccountData(
String userId,
String type,
Map<String, Object?> body, {
/// Waits for account data to come down from the sync loop before returns.
bool waitForSync = true,
}) async {
final syncFuture = onSync.stream
.where(
(syncUpdate) =>
syncUpdate.accountData?.any((data) => data.type == type) ?? false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this only checks the type while the previous version for checking for the exact data, also not clear how this fixes the original issue 🤔

)
.first;
await super.setAccountData(userId, type, body);
if (waitForSync) await syncFuture;
return;
}

/// Changes the password. You should either set oldPasswort or another authentication flow.
@override
Future<void> changePassword(
Expand Down
Loading