veilidchat/lib/old_to_refactor/providers/account.dart

146 lines
4.4 KiB
Dart
Raw Normal View History

2023-12-21 12:10:54 -05:00
import 'package:freezed_annotation/freezed_annotation.dart';
2023-07-28 20:36:05 -04:00
import 'package:riverpod_annotation/riverpod_annotation.dart';
2023-12-26 20:26:54 -05:00
import '../../entities/local_account.dart';
import '../../entities/user_login.dart';
import '../../proto/proto.dart' as proto;
import '../../veilid_support/veilid_support.dart';
import '../../local_accounts/local_accounts.dart';
2023-07-28 20:36:05 -04:00
import 'logins.dart';
part 'account.g.dart';
enum AccountInfoStatus {
noAccount,
accountInvalid,
accountLocked,
accountReady,
}
2023-12-21 12:10:54 -05:00
@immutable
2023-07-28 20:36:05 -04:00
class AccountInfo {
2023-12-21 12:10:54 -05:00
const AccountInfo({
2023-07-28 20:36:05 -04:00
required this.status,
required this.active,
this.account,
});
2023-12-21 12:10:54 -05:00
final AccountInfoStatus status;
final bool active;
final proto.Account? account;
2023-07-28 20:36:05 -04:00
}
2023-08-01 00:39:50 -04:00
/// Get an account from the identity key and if it is logged in and we
/// have its secret available, return the account record contents
2023-07-28 20:36:05 -04:00
@riverpod
2023-12-21 12:10:54 -05:00
Future<AccountInfo> fetchAccountInfo(FetchAccountInfoRef ref,
2023-07-28 20:36:05 -04:00
{required TypedKey accountMasterRecordKey}) async {
// Get which local account we want to fetch the profile for
final localAccount = await ref.watch(
fetchLocalAccountProvider(accountMasterRecordKey: accountMasterRecordKey)
.future);
if (localAccount == null) {
// Local account does not exist
2023-12-21 12:10:54 -05:00
return const AccountInfo(
status: AccountInfoStatus.noAccount, active: false);
2023-07-28 20:36:05 -04:00
}
// See if we've logged into this account or if it is locked
final activeUserLogin = await ref.watch(loginsProvider.future
.select((value) async => (await value).activeUserLogin));
final active = activeUserLogin == accountMasterRecordKey;
final login = await ref.watch(
fetchLoginProvider(accountMasterRecordKey: accountMasterRecordKey)
.future);
if (login == null) {
// Account was locked
return AccountInfo(status: AccountInfoStatus.accountLocked, active: active);
}
// Pull the account DHT key, decode it and return it
2023-08-01 00:39:50 -04:00
final pool = await DHTRecordPool.instance();
final account = await (await pool.openOwned(
login.accountRecordInfo.accountRecord,
parent: localAccount.identityMaster.identityRecordKey))
.scope((accountRec) => accountRec.getProtobuf(proto.Account.fromBuffer));
if (account == null) {
// Account could not be read or decrypted from DHT
2023-10-21 19:23:43 -04:00
ref.invalidateSelf();
2023-08-01 00:39:50 -04:00
return AccountInfo(
status: AccountInfoStatus.accountInvalid, active: active);
}
2023-07-28 20:36:05 -04:00
// Got account, decrypted and decoded
return AccountInfo(
status: AccountInfoStatus.accountReady, active: active, account: account);
}
2023-08-02 21:09:28 -04:00
2023-12-21 12:10:54 -05:00
@immutable
2023-08-02 21:09:28 -04:00
class ActiveAccountInfo {
2023-12-21 12:10:54 -05:00
const ActiveAccountInfo({
2023-08-02 21:09:28 -04:00
required this.localAccount,
required this.userLogin,
required this.account,
});
2023-12-21 12:10:54 -05:00
//
KeyPair getConversationWriter() {
final identityKey = localAccount.identityMaster.identityPublicKey;
final identitySecret = userLogin.identitySecret;
return KeyPair(key: identityKey, secret: identitySecret.value);
}
2023-08-02 21:09:28 -04:00
2023-12-21 12:10:54 -05:00
//
final LocalAccount localAccount;
final UserLogin userLogin;
final proto.Account account;
2023-08-02 21:09:28 -04:00
}
/// Get the active account info
@riverpod
2023-12-21 12:10:54 -05:00
Future<ActiveAccountInfo?> fetchActiveAccountInfo(
FetchActiveAccountInfoRef ref) async {
2023-08-02 21:09:28 -04:00
// See if we've logged into this account or if it is locked
final activeUserLogin = await ref.watch(loginsProvider.future
.select((value) async => (await value).activeUserLogin));
if (activeUserLogin == null) {
return null;
}
// Get the user login
final userLogin = await ref.watch(
fetchLoginProvider(accountMasterRecordKey: activeUserLogin).future);
if (userLogin == null) {
// Account was locked
return null;
}
// Get which local account we want to fetch the profile for
final localAccount = await ref.watch(
fetchLocalAccountProvider(accountMasterRecordKey: activeUserLogin)
.future);
if (localAccount == null) {
// Local account does not exist
return null;
}
// Pull the account DHT key, decode it and return it
final pool = await DHTRecordPool.instance();
final account = await (await pool.openOwned(
userLogin.accountRecordInfo.accountRecord,
parent: localAccount.identityMaster.identityRecordKey))
.scope((accountRec) => accountRec.getProtobuf(proto.Account.fromBuffer));
if (account == null) {
2023-10-21 19:23:43 -04:00
ref.invalidateSelf();
2023-08-02 21:09:28 -04:00
return null;
}
// Got account, decrypted and decoded
return ActiveAccountInfo(
localAccount: localAccount,
userLogin: userLogin,
account: account,
);
}