Skip to content

Commit

Permalink
feat: cache encryption for sensitive data
Browse files Browse the repository at this point in the history
  • Loading branch information
Kingkor Roy Tirtho committed Apr 25, 2023
1 parent 6760fe2 commit b110d83
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
2 changes: 1 addition & 1 deletion lib/provider/authentication_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class AuthenticationNotifier

bool get isLoggedIn => state != null;

AuthenticationNotifier() : super(null, "authentication");
AuthenticationNotifier() : super(null, "authentication", encrypted: true);

Timer? _refreshTimer;

Expand Down
54 changes: 51 additions & 3 deletions lib/utils/persisted_state_notifier.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,70 @@
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart';
import 'package:spotube/utils/primitive_utils.dart';

const secureStorage = FlutterSecureStorage();

abstract class PersistedStateNotifier<T> extends StateNotifier<T> {
final String cacheKey;
final bool encrypted;

FutureOr<void> onInit() {}

PersistedStateNotifier(
super.state,
this.cacheKey,
) {
this.cacheKey, {
this.encrypted = false,
}) {
_load().then((_) => onInit());
}

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);

if (json != null) {
Expand Down

0 comments on commit b110d83

Please sign in to comment.