claude refactor
This commit is contained in:
+51
-28
@@ -4,68 +4,91 @@ import 'dart:convert';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'accountModel.dart';
|
||||
import '../state/app/modules/account/bloc/account_bloc.dart';
|
||||
import '../state/app/modules/account/bloc/account_state.dart';
|
||||
|
||||
class AccountData {
|
||||
static const _usernameField = 'username';
|
||||
static const _passwordField = 'password';
|
||||
|
||||
|
||||
static const FlutterSecureStorage _secureStorage = FlutterSecureStorage(
|
||||
aOptions: AndroidOptions(encryptedSharedPreferences: true),
|
||||
);
|
||||
|
||||
static final AccountData _instance = AccountData._construct();
|
||||
final Future<SharedPreferences> _storage = SharedPreferences.getInstance();
|
||||
Completer<void> _populated = Completer();
|
||||
|
||||
factory AccountData() => _instance;
|
||||
|
||||
AccountData._construct() {
|
||||
_updateFromStorage();
|
||||
_migrateAndLoad();
|
||||
}
|
||||
|
||||
String? _username;
|
||||
String? _password;
|
||||
|
||||
String getUsername() {
|
||||
if(_username == null) throw Exception('Username not initialized');
|
||||
if (_username == null) throw Exception('Username not initialized');
|
||||
return _username!;
|
||||
}
|
||||
|
||||
String getPassword() {
|
||||
if(_password == null) throw Exception('Password not initialized');
|
||||
if (_password == null) throw Exception('Password not initialized');
|
||||
return _password!;
|
||||
}
|
||||
|
||||
String getUserSecret() => sha512.convert(utf8.encode('${AccountData().getUsername()}:${AccountData().getPassword()}')).toString();
|
||||
String getUserSecret() =>
|
||||
sha512.convert(utf8.encode('${getUsername()}:${getPassword()}')).toString();
|
||||
|
||||
Future<String> getDeviceId() async => sha512.convert(utf8.encode('${getUserSecret()}@${await FirebaseMessaging.instance.getToken()}')).toString();
|
||||
Future<String> getDeviceId() async => sha512
|
||||
.convert(utf8.encode('${getUserSecret()}@${await FirebaseMessaging.instance.getToken()}'))
|
||||
.toString();
|
||||
|
||||
Future<void> setData(String username, String password) async {
|
||||
var storage = await _storage;
|
||||
|
||||
storage.setString(_usernameField, username);
|
||||
storage.setString(_passwordField, password);
|
||||
await _updateFromStorage();
|
||||
await _secureStorage.write(key: _usernameField, value: username);
|
||||
await _secureStorage.write(key: _passwordField, value: password);
|
||||
_username = username;
|
||||
_password = password;
|
||||
if (!_populated.isCompleted) _populated.complete();
|
||||
}
|
||||
|
||||
Future<void> removeData({BuildContext? context}) async {
|
||||
_populated = Completer();
|
||||
|
||||
if(context != null) Provider.of<AccountModel>(context, listen: false).setState(AccountModelState.loggedOut);
|
||||
|
||||
var storage = await _storage;
|
||||
await storage.remove(_usernameField);
|
||||
await storage.remove(_passwordField);
|
||||
if (context != null) {
|
||||
context.read<AccountBloc>().setStatus(AccountStatus.loggedOut);
|
||||
}
|
||||
_username = null;
|
||||
_password = null;
|
||||
await _secureStorage.delete(key: _usernameField);
|
||||
await _secureStorage.delete(key: _passwordField);
|
||||
}
|
||||
|
||||
Future<void> _updateFromStorage() async {
|
||||
var storage = await _storage;
|
||||
//await storage.reload(); // This line was the cause of the first rejected google play upload :(
|
||||
if(storage.containsKey(_usernameField) && storage.containsKey(_passwordField)) {
|
||||
_username = storage.getString(_usernameField);
|
||||
_password = storage.getString(_passwordField);
|
||||
Future<void> _migrateAndLoad() async {
|
||||
await _migrateFromLegacyStorage();
|
||||
_username = await _secureStorage.read(key: _usernameField);
|
||||
_password = await _secureStorage.read(key: _passwordField);
|
||||
if (!_populated.isCompleted) _populated.complete();
|
||||
}
|
||||
|
||||
// Move credentials from the old SharedPreferences plain-text storage into the
|
||||
// platform's secure keystore. Run once per install and clear the legacy keys.
|
||||
Future<void> _migrateFromLegacyStorage() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final legacyUsername = prefs.getString(_usernameField);
|
||||
final legacyPassword = prefs.getString(_passwordField);
|
||||
if (legacyUsername == null || legacyPassword == null) return;
|
||||
|
||||
final hasSecure = (await _secureStorage.read(key: _usernameField)) != null;
|
||||
if (!hasSecure) {
|
||||
await _secureStorage.write(key: _usernameField, value: legacyUsername);
|
||||
await _secureStorage.write(key: _passwordField, value: legacyPassword);
|
||||
}
|
||||
if(!_populated.isCompleted) _populated.complete();
|
||||
await prefs.remove(_usernameField);
|
||||
await prefs.remove(_passwordField);
|
||||
}
|
||||
|
||||
Future<bool> waitForPopulation() async {
|
||||
@@ -76,7 +99,7 @@ class AccountData {
|
||||
bool isPopulated() => _username != null && _password != null;
|
||||
|
||||
String buildHttpAuthString() {
|
||||
if(!isPopulated()) throw Exception('AccountData (e.g. username or password) is not initialized!');
|
||||
if (!isPopulated()) throw Exception('AccountData (e.g. username or password) is not initialized!');
|
||||
return '$_username:$_password';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user