analyzeSecrets method

Map<String, Set<String>> analyzeSecrets()

Implementation

Map<String, Set<String>> analyzeSecrets() {
  final secretsCache = _secretsCache;
  if (secretsCache != null) {
    // deep-copy so that we can do modifications
    final newSecrets = <String, Set<String>>{};
    for (final s in secretsCache.entries) {
      newSecrets[s.key] = Set<String>.from(s.value);
    }
    return newSecrets;
  }
  final secrets = <String, Set<String>>{};
  for (final entry in client.accountData.entries) {
    final type = entry.key;
    final event = entry.value;
    final encryptedContent =
        event.content.tryGetMap<String, Object?>('encrypted');
    if (encryptedContent == null) {
      continue;
    }
    final validKeys = <String>{};
    final invalidKeys = <String>{};
    for (final keyEntry in encryptedContent.entries) {
      final key = keyEntry.key;
      final value = keyEntry.value;
      if (value is! Map) {
        // we don't add the key to invalidKeys as this was not a proper secret anyways!
        continue;
      }
      if (value['iv'] is! String ||
          value['ciphertext'] is! String ||
          value['mac'] is! String) {
        invalidKeys.add(key);
        continue;
      }
      if (!encryption.ssss.isKeyValid(key)) {
        invalidKeys.add(key);
        continue;
      }
      validKeys.add(key);
    }
    if (validKeys.isEmpty && invalidKeys.isEmpty) {
      continue; // this didn't contain any keys anyways!
    }
    // if there are no valid keys and only invalid keys then the validKeys set will be empty
    // from that we know that there were errors with this secret and that we won't be able to migrate it
    secrets[type] = validKeys;
  }
  _secretsCache = secrets;
  return analyzeSecrets();
}