feat: cache encryption for sensitive data

This commit is contained in:
Kingkor Roy Tirtho 2023-04-25 23:29:54 +06:00
parent 6760fe2437
commit b110d83456
2 changed files with 52 additions and 4 deletions

View File

@ -79,7 +79,7 @@ class AuthenticationNotifier
bool get isLoggedIn => state != null; bool get isLoggedIn => state != null;
AuthenticationNotifier() : super(null, "authentication"); AuthenticationNotifier() : super(null, "authentication", encrypted: true);
Timer? _refreshTimer; Timer? _refreshTimer;

View File

@ -1,22 +1,70 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:spotube/utils/primitive_utils.dart';
const secureStorage = FlutterSecureStorage();
abstract class PersistedStateNotifier<T> extends StateNotifier<T> { abstract class PersistedStateNotifier<T> extends StateNotifier<T> {
final String cacheKey; final String cacheKey;
final bool encrypted;
FutureOr<void> onInit() {} FutureOr<void> onInit() {}
PersistedStateNotifier( PersistedStateNotifier(
super.state, super.state,
this.cacheKey, this.cacheKey, {
) { this.encrypted = false,
}) {
_load().then((_) => onInit()); _load().then((_) => onInit());
} }
Future<void> _load() async { Future<void> _load() async {
final box = await Hive.openLazyBox("spotube_cache"); final LazyBox box;
if (encrypted) {
String? boxName =
await secureStorage.read(key: "oss.krtirtho.spotube.box_name");
if (boxName == null) {
await secureStorage.write(
key: "oss.krtirtho.spotube.box_name",
value: ".spotube-${PrimitiveUtils.uuid.v4()}",
);
boxName =
await secureStorage.read(key: "oss.krtirtho.spotube.box_name");
} else {
boxName = ".spotube-$boxName";
}
final rawKey =
await secureStorage.read(key: "oss.krtirtho.spotube.$boxName");
Uint8List? encryptionKey =
rawKey == null ? null : base64Url.decode(rawKey);
if (encryptionKey == null) {
await secureStorage.write(
key: "oss.krtirtho.spotube.$boxName",
value: base64UrlEncode(Hive.generateSecureKey()),
);
encryptionKey = base64Url.decode(
(await secureStorage.read(key: "oss.krtirtho.spotube.$boxName"))!,
);
}
box = await Hive.openLazyBox(
boxName!,
encryptionCipher: HiveAesCipher(encryptionKey),
);
} else {
box = await Hive.openLazyBox("spotube_cache");
}
final json = await box.get(cacheKey); final json = await box.get(cacheKey);
if (json != null) { if (json != null) {