mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
chore: add encrypted text column support
This commit is contained in:
parent
bf6cec8d69
commit
a799ca55bc
@ -27,6 +27,7 @@ import 'package:spotube/provider/palette_provider.dart';
|
||||
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
|
||||
import 'package:spotube/services/audio_player/audio_player.dart';
|
||||
import 'package:spotube/services/cli/cli.dart';
|
||||
import 'package:spotube/services/kv_store/encrypted_kv_store.dart';
|
||||
import 'package:spotube/services/kv_store/kv_store.dart';
|
||||
import 'package:spotube/services/logger/logger.dart';
|
||||
import 'package:spotube/services/wm_tools/wm_tools.dart';
|
||||
@ -76,6 +77,7 @@ Future<void> main(List<String> rawArgs) async {
|
||||
}
|
||||
|
||||
await KVStoreService.initialize();
|
||||
await EncryptedKvStoreService.initialize();
|
||||
|
||||
final hiveCacheDir =
|
||||
kIsWeb ? null : (await getApplicationSupportDirectory()).path;
|
||||
|
@ -4,11 +4,14 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:encrypt/encrypt.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/services/kv_store/encrypted_kv_store.dart';
|
||||
import 'package:spotube/services/kv_store/kv_store.dart';
|
||||
import 'package:spotube/services/sourced_track/enums.dart';
|
||||
import 'package:flutter/material.dart' hide Table;
|
||||
import 'package:flutter/material.dart' hide Table, Key;
|
||||
import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart';
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:sqlite3/sqlite3.dart';
|
||||
@ -24,6 +27,7 @@ part 'tables/blacklist.dart';
|
||||
part 'typeconverters/color.dart';
|
||||
part 'typeconverters/locale.dart';
|
||||
part 'typeconverters/string_list.dart';
|
||||
part 'typeconverters/encrypted_text.dart';
|
||||
|
||||
@DriftDatabase(
|
||||
tables: [
|
||||
|
39
lib/models/database/typeconverters/encrypted_text.dart
Normal file
39
lib/models/database/typeconverters/encrypted_text.dart
Normal file
@ -0,0 +1,39 @@
|
||||
part of '../database.dart';
|
||||
|
||||
class DecryptedText {
|
||||
final String value;
|
||||
const DecryptedText(this.value);
|
||||
|
||||
static Encrypter? _encrypter;
|
||||
|
||||
factory DecryptedText.decrypted(String value) {
|
||||
_encrypter ??= Encrypter(
|
||||
Salsa20(
|
||||
Key.fromUtf8(EncryptedKvStoreService.encryptionKeySync),
|
||||
),
|
||||
);
|
||||
|
||||
return DecryptedText(
|
||||
_encrypter!.decrypt(
|
||||
Encrypted.fromBase64(value),
|
||||
iv: KVStoreService.ivKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String encrypt() {
|
||||
return _encrypter!.encrypt(value, iv: KVStoreService.ivKey).base64;
|
||||
}
|
||||
}
|
||||
|
||||
class EncryptedTextConverter extends TypeConverter<DecryptedText, String> {
|
||||
@override
|
||||
DecryptedText fromSql(String fromDb) {
|
||||
return DecryptedText.decrypted(fromDb);
|
||||
}
|
||||
|
||||
@override
|
||||
String toSql(DecryptedText value) {
|
||||
return value.encrypt();
|
||||
}
|
||||
}
|
43
lib/services/kv_store/encrypted_kv_store.dart
Normal file
43
lib/services/kv_store/encrypted_kv_store.dart
Normal file
@ -0,0 +1,43 @@
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:spotube/services/kv_store/kv_store.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
abstract class EncryptedKvStoreService {
|
||||
static const _storage = FlutterSecureStorage(
|
||||
aOptions: AndroidOptions(
|
||||
encryptedSharedPreferences: true,
|
||||
),
|
||||
);
|
||||
|
||||
static late final String _encryptionKeySync;
|
||||
|
||||
static Future<void> initialize() async {
|
||||
_encryptionKeySync = await encryptionKey;
|
||||
}
|
||||
|
||||
static String get encryptionKeySync => _encryptionKeySync;
|
||||
|
||||
static Future<String> get encryptionKey async {
|
||||
try {
|
||||
final value = await _storage.read(key: 'encryption');
|
||||
final key = const Uuid().v4();
|
||||
|
||||
if (value == null) {
|
||||
await setEncryptionKey(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
return value;
|
||||
} catch (e) {
|
||||
return KVStoreService.encryptionKey;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> setEncryptionKey(String key) async {
|
||||
try {
|
||||
await _storage.write(key: 'encryption', value: key);
|
||||
} catch (e) {
|
||||
await KVStoreService.setEncryptionKey(key);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:encrypt/encrypt.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:spotube/services/wm_tools/wm_tools.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
abstract class KVStoreService {
|
||||
static SharedPreferences? _sharedPreferences;
|
||||
@ -43,4 +45,37 @@ abstract class KVStoreService {
|
||||
value.toJson(),
|
||||
),
|
||||
);
|
||||
|
||||
static String get encryptionKey {
|
||||
final value = sharedPreferences.getString('encryption');
|
||||
|
||||
final key = const Uuid().v4();
|
||||
if (value == null) {
|
||||
setEncryptionKey(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static Future<void> setEncryptionKey(String key) async {
|
||||
await sharedPreferences.setString('encryption', key);
|
||||
}
|
||||
|
||||
static IV get ivKey {
|
||||
final iv = sharedPreferences.getString('iv');
|
||||
final value = IV.fromSecureRandom(8);
|
||||
|
||||
if (iv == null) {
|
||||
setIVKey(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return IV.fromBase64(iv);
|
||||
}
|
||||
|
||||
static Future<void> setIVKey(IV iv) async {
|
||||
await sharedPreferences.setString('iv', iv.base64);
|
||||
}
|
||||
}
|
||||
|
24
pubspec.lock
24
pubspec.lock
@ -57,6 +57,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.0"
|
||||
asn1lib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: asn1lib
|
||||
sha256: "58082b3f0dca697204dbab0ef9ff208bfaea7767ea771076af9a343488428dda"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.3"
|
||||
async:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -539,6 +547,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.13"
|
||||
encrypt:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: encrypt
|
||||
sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.3"
|
||||
envied:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1670,6 +1686,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.8"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pointycastle
|
||||
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.9.1"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -124,6 +124,7 @@ dependencies:
|
||||
drift: ^2.18.0
|
||||
sqlite3_flutter_libs: ^0.5.23
|
||||
sqlite3: ^2.4.3
|
||||
encrypt: ^5.0.3
|
||||
|
||||
dev_dependencies:
|
||||
build_runner: ^2.4.11
|
||||
|
Loading…
Reference in New Issue
Block a user