getAll method

  1. @override
Future<Map<String, String>> getAll()
override

Returns every xpub and hdpubkey secret, decrypted.

All or nothing: if any row cannot be decrypted (no key for its version, wrong key, tampered data) this throws a SecureStorageException naming every such row, rather than returning a partial map that looks complete.

Implementation

@override
Future<Map<String, String>> getAll() async {
  final Result result;
  try {
    result = await _pool.execute(
      Sql.named('''
        SELECT key_name, encrypted_value, nonce, key_version
        FROM secure_secrets
        WHERE key_name LIKE @xpub_pattern
           OR key_name LIKE @hdpubkey_pattern
      '''),
      parameters: {
        'xpub_pattern': '$_xpubKeyPrefix%',
        'hdpubkey_pattern': '$_hdPubKeyPrefix%',
      },
    );
  } catch (e) {
    throw SecureStorageException('Failed to retrieve all secrets: $e', e);
  }

  final secrets = <String, String>{};
  final failures = <SecureStorageException>[];
  for (final row in result) {
    try {
      final keyName = row[0] as String;
      secrets[keyName] = await _decryptRow(
        keyName,
        row[1] as Uint8List,
        row[2] as Uint8List,
        row[3] as int,
      );
    } on SecureStorageException catch (e) {
      failures.add(e);
    }
  }

  if (failures.isNotEmpty) {
    throw SecureStorageException(
      'Failed to decrypt ${failures.length} of ${result.length} secrets: '
      '${failures.map((e) => e.message).join('; ')}',
      failures,
    );
  }
  return secrets;
}