mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-01-24 14:31:02 -05:00
account work
This commit is contained in:
parent
f44fdb8eeb
commit
90fc2e5f85
@ -4,6 +4,19 @@ import 'package:veilid/veilid.dart';
|
|||||||
part 'identity.freezed.dart';
|
part 'identity.freezed.dart';
|
||||||
part 'identity.g.dart';
|
part 'identity.g.dart';
|
||||||
|
|
||||||
|
// AccountOwnerInfo is the key and owner info for the account dht key that is
|
||||||
|
// stored in the identity key
|
||||||
|
@freezed
|
||||||
|
class AccountOwnerInfo with _$AccountOwnerInfo {
|
||||||
|
const factory AccountOwnerInfo({
|
||||||
|
// Top level account keys and secrets
|
||||||
|
required Map<String, TypedKeyPair> accountKeyPairs,
|
||||||
|
}) = _AccountOwnerInfo;
|
||||||
|
|
||||||
|
factory AccountOwnerInfo.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$AccountOwnerInfoFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
// Identity Key points to accounts associated with this identity
|
// Identity Key points to accounts associated with this identity
|
||||||
// accounts field has a map of service name or uuid to account key pairs
|
// accounts field has a map of service name or uuid to account key pairs
|
||||||
// DHT Schema: DFLT(1)
|
// DHT Schema: DFLT(1)
|
||||||
@ -55,6 +68,16 @@ class IdentityMaster with _$IdentityMaster {
|
|||||||
_$IdentityMasterFromJson(json);
|
_$IdentityMasterFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension IdentityMasterExtension on IdentityMaster {
|
||||||
|
KeyPair identityWriter(SecretKey secret) {
|
||||||
|
return KeyPair(key: identityPublicKey, secret: secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyPair masterWriter(SecretKey secret) {
|
||||||
|
return KeyPair(key: masterPublicKey, secret: secret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Identity Master with secrets
|
// Identity Master with secrets
|
||||||
// Not freezed because we never persist this class in its entirety
|
// Not freezed because we never persist this class in its entirety
|
||||||
class IdentityMasterWithSecrets {
|
class IdentityMasterWithSecrets {
|
||||||
|
@ -14,6 +14,157 @@ T _$identity<T>(T value) => value;
|
|||||||
final _privateConstructorUsedError = UnsupportedError(
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
||||||
|
|
||||||
|
AccountOwnerInfo _$AccountOwnerInfoFromJson(Map<String, dynamic> json) {
|
||||||
|
return _AccountOwnerInfo.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$AccountOwnerInfo {
|
||||||
|
// Top level account keys and secrets
|
||||||
|
Map<String, TypedKeyPair> get accountKeyPairs =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
$AccountOwnerInfoCopyWith<AccountOwnerInfo> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $AccountOwnerInfoCopyWith<$Res> {
|
||||||
|
factory $AccountOwnerInfoCopyWith(
|
||||||
|
AccountOwnerInfo value, $Res Function(AccountOwnerInfo) then) =
|
||||||
|
_$AccountOwnerInfoCopyWithImpl<$Res, AccountOwnerInfo>;
|
||||||
|
@useResult
|
||||||
|
$Res call({Map<String, TypedKeyPair> accountKeyPairs});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$AccountOwnerInfoCopyWithImpl<$Res, $Val extends AccountOwnerInfo>
|
||||||
|
implements $AccountOwnerInfoCopyWith<$Res> {
|
||||||
|
_$AccountOwnerInfoCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? accountKeyPairs = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
accountKeyPairs: null == accountKeyPairs
|
||||||
|
? _value.accountKeyPairs
|
||||||
|
: accountKeyPairs // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, TypedKeyPair>,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$_AccountOwnerInfoCopyWith<$Res>
|
||||||
|
implements $AccountOwnerInfoCopyWith<$Res> {
|
||||||
|
factory _$$_AccountOwnerInfoCopyWith(
|
||||||
|
_$_AccountOwnerInfo value, $Res Function(_$_AccountOwnerInfo) then) =
|
||||||
|
__$$_AccountOwnerInfoCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({Map<String, TypedKeyPair> accountKeyPairs});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$_AccountOwnerInfoCopyWithImpl<$Res>
|
||||||
|
extends _$AccountOwnerInfoCopyWithImpl<$Res, _$_AccountOwnerInfo>
|
||||||
|
implements _$$_AccountOwnerInfoCopyWith<$Res> {
|
||||||
|
__$$_AccountOwnerInfoCopyWithImpl(
|
||||||
|
_$_AccountOwnerInfo _value, $Res Function(_$_AccountOwnerInfo) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? accountKeyPairs = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$_AccountOwnerInfo(
|
||||||
|
accountKeyPairs: null == accountKeyPairs
|
||||||
|
? _value._accountKeyPairs
|
||||||
|
: accountKeyPairs // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, TypedKeyPair>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$_AccountOwnerInfo implements _AccountOwnerInfo {
|
||||||
|
const _$_AccountOwnerInfo(
|
||||||
|
{required final Map<String, TypedKeyPair> accountKeyPairs})
|
||||||
|
: _accountKeyPairs = accountKeyPairs;
|
||||||
|
|
||||||
|
factory _$_AccountOwnerInfo.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$_AccountOwnerInfoFromJson(json);
|
||||||
|
|
||||||
|
// Top level account keys and secrets
|
||||||
|
final Map<String, TypedKeyPair> _accountKeyPairs;
|
||||||
|
// Top level account keys and secrets
|
||||||
|
@override
|
||||||
|
Map<String, TypedKeyPair> get accountKeyPairs {
|
||||||
|
if (_accountKeyPairs is EqualUnmodifiableMapView) return _accountKeyPairs;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableMapView(_accountKeyPairs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AccountOwnerInfo(accountKeyPairs: $accountKeyPairs)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$_AccountOwnerInfo &&
|
||||||
|
const DeepCollectionEquality()
|
||||||
|
.equals(other._accountKeyPairs, _accountKeyPairs));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType, const DeepCollectionEquality().hash(_accountKeyPairs));
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$_AccountOwnerInfoCopyWith<_$_AccountOwnerInfo> get copyWith =>
|
||||||
|
__$$_AccountOwnerInfoCopyWithImpl<_$_AccountOwnerInfo>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$_AccountOwnerInfoToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _AccountOwnerInfo implements AccountOwnerInfo {
|
||||||
|
const factory _AccountOwnerInfo(
|
||||||
|
{required final Map<String, TypedKeyPair> accountKeyPairs}) =
|
||||||
|
_$_AccountOwnerInfo;
|
||||||
|
|
||||||
|
factory _AccountOwnerInfo.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$_AccountOwnerInfo.fromJson;
|
||||||
|
|
||||||
|
@override // Top level account keys and secrets
|
||||||
|
Map<String, TypedKeyPair> get accountKeyPairs;
|
||||||
|
@override
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$_AccountOwnerInfoCopyWith<_$_AccountOwnerInfo> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
Identity _$IdentityFromJson(Map<String, dynamic> json) {
|
Identity _$IdentityFromJson(Map<String, dynamic> json) {
|
||||||
return _Identity.fromJson(json);
|
return _Identity.fromJson(json);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,19 @@ part of 'identity.dart';
|
|||||||
// JsonSerializableGenerator
|
// JsonSerializableGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$_AccountOwnerInfo _$$_AccountOwnerInfoFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$_AccountOwnerInfo(
|
||||||
|
accountKeyPairs: (json['account_key_pairs'] as Map<String, dynamic>).map(
|
||||||
|
(k, e) => MapEntry(k, TypedKeyPair.fromJson(e)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$_AccountOwnerInfoToJson(_$_AccountOwnerInfo instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'account_key_pairs':
|
||||||
|
instance.accountKeyPairs.map((k, e) => MapEntry(k, e.toJson())),
|
||||||
|
};
|
||||||
|
|
||||||
_$_Identity _$$_IdentityFromJson(Map<String, dynamic> json) => _$_Identity(
|
_$_Identity _$$_IdentityFromJson(Map<String, dynamic> json) => _$_Identity(
|
||||||
accountKeyPairs: (json['account_key_pairs'] as Map<String, dynamic>).map(
|
accountKeyPairs: (json['account_key_pairs'] as Map<String, dynamic>).map(
|
||||||
(k, e) => MapEntry(k, TypedKeyPair.fromJson(e)),
|
(k, e) => MapEntry(k, TypedKeyPair.fromJson(e)),
|
||||||
|
@ -25,6 +25,9 @@ mixin _$LocalAccount {
|
|||||||
throw _privateConstructorUsedError; // The encrypted identity secret that goes with the identityPublicKey
|
throw _privateConstructorUsedError; // The encrypted identity secret that goes with the identityPublicKey
|
||||||
@Uint8ListJsonConverter()
|
@Uint8ListJsonConverter()
|
||||||
Uint8List get identitySecretKeyBytes =>
|
Uint8List get identitySecretKeyBytes =>
|
||||||
|
throw _privateConstructorUsedError; // The salt for the identity secret key encryption
|
||||||
|
@Uint8ListJsonConverter()
|
||||||
|
Uint8List get identitySecretSaltBytes =>
|
||||||
throw _privateConstructorUsedError; // The kind of encryption input used on the account
|
throw _privateConstructorUsedError; // The kind of encryption input used on the account
|
||||||
EncryptionKeyType get encryptionKeyType =>
|
EncryptionKeyType get encryptionKeyType =>
|
||||||
throw _privateConstructorUsedError; // If account is not hidden, password can be retrieved via
|
throw _privateConstructorUsedError; // If account is not hidden, password can be retrieved via
|
||||||
@ -48,6 +51,7 @@ abstract class $LocalAccountCopyWith<$Res> {
|
|||||||
$Res call(
|
$Res call(
|
||||||
{IdentityMaster identityMaster,
|
{IdentityMaster identityMaster,
|
||||||
@Uint8ListJsonConverter() Uint8List identitySecretKeyBytes,
|
@Uint8ListJsonConverter() Uint8List identitySecretKeyBytes,
|
||||||
|
@Uint8ListJsonConverter() Uint8List identitySecretSaltBytes,
|
||||||
EncryptionKeyType encryptionKeyType,
|
EncryptionKeyType encryptionKeyType,
|
||||||
bool biometricsEnabled,
|
bool biometricsEnabled,
|
||||||
bool hiddenAccount});
|
bool hiddenAccount});
|
||||||
@ -70,6 +74,7 @@ class _$LocalAccountCopyWithImpl<$Res, $Val extends LocalAccount>
|
|||||||
$Res call({
|
$Res call({
|
||||||
Object? identityMaster = null,
|
Object? identityMaster = null,
|
||||||
Object? identitySecretKeyBytes = null,
|
Object? identitySecretKeyBytes = null,
|
||||||
|
Object? identitySecretSaltBytes = null,
|
||||||
Object? encryptionKeyType = null,
|
Object? encryptionKeyType = null,
|
||||||
Object? biometricsEnabled = null,
|
Object? biometricsEnabled = null,
|
||||||
Object? hiddenAccount = null,
|
Object? hiddenAccount = null,
|
||||||
@ -83,6 +88,10 @@ class _$LocalAccountCopyWithImpl<$Res, $Val extends LocalAccount>
|
|||||||
? _value.identitySecretKeyBytes
|
? _value.identitySecretKeyBytes
|
||||||
: identitySecretKeyBytes // ignore: cast_nullable_to_non_nullable
|
: identitySecretKeyBytes // ignore: cast_nullable_to_non_nullable
|
||||||
as Uint8List,
|
as Uint8List,
|
||||||
|
identitySecretSaltBytes: null == identitySecretSaltBytes
|
||||||
|
? _value.identitySecretSaltBytes
|
||||||
|
: identitySecretSaltBytes // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Uint8List,
|
||||||
encryptionKeyType: null == encryptionKeyType
|
encryptionKeyType: null == encryptionKeyType
|
||||||
? _value.encryptionKeyType
|
? _value.encryptionKeyType
|
||||||
: encryptionKeyType // ignore: cast_nullable_to_non_nullable
|
: encryptionKeyType // ignore: cast_nullable_to_non_nullable
|
||||||
@ -118,6 +127,7 @@ abstract class _$$_LocalAccountCopyWith<$Res>
|
|||||||
$Res call(
|
$Res call(
|
||||||
{IdentityMaster identityMaster,
|
{IdentityMaster identityMaster,
|
||||||
@Uint8ListJsonConverter() Uint8List identitySecretKeyBytes,
|
@Uint8ListJsonConverter() Uint8List identitySecretKeyBytes,
|
||||||
|
@Uint8ListJsonConverter() Uint8List identitySecretSaltBytes,
|
||||||
EncryptionKeyType encryptionKeyType,
|
EncryptionKeyType encryptionKeyType,
|
||||||
bool biometricsEnabled,
|
bool biometricsEnabled,
|
||||||
bool hiddenAccount});
|
bool hiddenAccount});
|
||||||
@ -139,6 +149,7 @@ class __$$_LocalAccountCopyWithImpl<$Res>
|
|||||||
$Res call({
|
$Res call({
|
||||||
Object? identityMaster = null,
|
Object? identityMaster = null,
|
||||||
Object? identitySecretKeyBytes = null,
|
Object? identitySecretKeyBytes = null,
|
||||||
|
Object? identitySecretSaltBytes = null,
|
||||||
Object? encryptionKeyType = null,
|
Object? encryptionKeyType = null,
|
||||||
Object? biometricsEnabled = null,
|
Object? biometricsEnabled = null,
|
||||||
Object? hiddenAccount = null,
|
Object? hiddenAccount = null,
|
||||||
@ -152,6 +163,10 @@ class __$$_LocalAccountCopyWithImpl<$Res>
|
|||||||
? _value.identitySecretKeyBytes
|
? _value.identitySecretKeyBytes
|
||||||
: identitySecretKeyBytes // ignore: cast_nullable_to_non_nullable
|
: identitySecretKeyBytes // ignore: cast_nullable_to_non_nullable
|
||||||
as Uint8List,
|
as Uint8List,
|
||||||
|
identitySecretSaltBytes: null == identitySecretSaltBytes
|
||||||
|
? _value.identitySecretSaltBytes
|
||||||
|
: identitySecretSaltBytes // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Uint8List,
|
||||||
encryptionKeyType: null == encryptionKeyType
|
encryptionKeyType: null == encryptionKeyType
|
||||||
? _value.encryptionKeyType
|
? _value.encryptionKeyType
|
||||||
: encryptionKeyType // ignore: cast_nullable_to_non_nullable
|
: encryptionKeyType // ignore: cast_nullable_to_non_nullable
|
||||||
@ -174,6 +189,7 @@ class _$_LocalAccount implements _LocalAccount {
|
|||||||
const _$_LocalAccount(
|
const _$_LocalAccount(
|
||||||
{required this.identityMaster,
|
{required this.identityMaster,
|
||||||
@Uint8ListJsonConverter() required this.identitySecretKeyBytes,
|
@Uint8ListJsonConverter() required this.identitySecretKeyBytes,
|
||||||
|
@Uint8ListJsonConverter() required this.identitySecretSaltBytes,
|
||||||
required this.encryptionKeyType,
|
required this.encryptionKeyType,
|
||||||
required this.biometricsEnabled,
|
required this.biometricsEnabled,
|
||||||
required this.hiddenAccount});
|
required this.hiddenAccount});
|
||||||
@ -188,6 +204,10 @@ class _$_LocalAccount implements _LocalAccount {
|
|||||||
@override
|
@override
|
||||||
@Uint8ListJsonConverter()
|
@Uint8ListJsonConverter()
|
||||||
final Uint8List identitySecretKeyBytes;
|
final Uint8List identitySecretKeyBytes;
|
||||||
|
// The salt for the identity secret key encryption
|
||||||
|
@override
|
||||||
|
@Uint8ListJsonConverter()
|
||||||
|
final Uint8List identitySecretSaltBytes;
|
||||||
// The kind of encryption input used on the account
|
// The kind of encryption input used on the account
|
||||||
@override
|
@override
|
||||||
final EncryptionKeyType encryptionKeyType;
|
final EncryptionKeyType encryptionKeyType;
|
||||||
@ -201,7 +221,7 @@ class _$_LocalAccount implements _LocalAccount {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'LocalAccount(identityMaster: $identityMaster, identitySecretKeyBytes: $identitySecretKeyBytes, encryptionKeyType: $encryptionKeyType, biometricsEnabled: $biometricsEnabled, hiddenAccount: $hiddenAccount)';
|
return 'LocalAccount(identityMaster: $identityMaster, identitySecretKeyBytes: $identitySecretKeyBytes, identitySecretSaltBytes: $identitySecretSaltBytes, encryptionKeyType: $encryptionKeyType, biometricsEnabled: $biometricsEnabled, hiddenAccount: $hiddenAccount)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -213,6 +233,8 @@ class _$_LocalAccount implements _LocalAccount {
|
|||||||
other.identityMaster == identityMaster) &&
|
other.identityMaster == identityMaster) &&
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
.equals(other.identitySecretKeyBytes, identitySecretKeyBytes) &&
|
.equals(other.identitySecretKeyBytes, identitySecretKeyBytes) &&
|
||||||
|
const DeepCollectionEquality().equals(
|
||||||
|
other.identitySecretSaltBytes, identitySecretSaltBytes) &&
|
||||||
(identical(other.encryptionKeyType, encryptionKeyType) ||
|
(identical(other.encryptionKeyType, encryptionKeyType) ||
|
||||||
other.encryptionKeyType == encryptionKeyType) &&
|
other.encryptionKeyType == encryptionKeyType) &&
|
||||||
(identical(other.biometricsEnabled, biometricsEnabled) ||
|
(identical(other.biometricsEnabled, biometricsEnabled) ||
|
||||||
@ -227,6 +249,7 @@ class _$_LocalAccount implements _LocalAccount {
|
|||||||
runtimeType,
|
runtimeType,
|
||||||
identityMaster,
|
identityMaster,
|
||||||
const DeepCollectionEquality().hash(identitySecretKeyBytes),
|
const DeepCollectionEquality().hash(identitySecretKeyBytes),
|
||||||
|
const DeepCollectionEquality().hash(identitySecretSaltBytes),
|
||||||
encryptionKeyType,
|
encryptionKeyType,
|
||||||
biometricsEnabled,
|
biometricsEnabled,
|
||||||
hiddenAccount);
|
hiddenAccount);
|
||||||
@ -249,6 +272,8 @@ abstract class _LocalAccount implements LocalAccount {
|
|||||||
const factory _LocalAccount(
|
const factory _LocalAccount(
|
||||||
{required final IdentityMaster identityMaster,
|
{required final IdentityMaster identityMaster,
|
||||||
@Uint8ListJsonConverter() required final Uint8List identitySecretKeyBytes,
|
@Uint8ListJsonConverter() required final Uint8List identitySecretKeyBytes,
|
||||||
|
@Uint8ListJsonConverter()
|
||||||
|
required final Uint8List identitySecretSaltBytes,
|
||||||
required final EncryptionKeyType encryptionKeyType,
|
required final EncryptionKeyType encryptionKeyType,
|
||||||
required final bool biometricsEnabled,
|
required final bool biometricsEnabled,
|
||||||
required final bool hiddenAccount}) = _$_LocalAccount;
|
required final bool hiddenAccount}) = _$_LocalAccount;
|
||||||
@ -261,6 +286,9 @@ abstract class _LocalAccount implements LocalAccount {
|
|||||||
@override // The encrypted identity secret that goes with the identityPublicKey
|
@override // The encrypted identity secret that goes with the identityPublicKey
|
||||||
@Uint8ListJsonConverter()
|
@Uint8ListJsonConverter()
|
||||||
Uint8List get identitySecretKeyBytes;
|
Uint8List get identitySecretKeyBytes;
|
||||||
|
@override // The salt for the identity secret key encryption
|
||||||
|
@Uint8ListJsonConverter()
|
||||||
|
Uint8List get identitySecretSaltBytes;
|
||||||
@override // The kind of encryption input used on the account
|
@override // The kind of encryption input used on the account
|
||||||
EncryptionKeyType get encryptionKeyType;
|
EncryptionKeyType get encryptionKeyType;
|
||||||
@override // If account is not hidden, password can be retrieved via
|
@override // If account is not hidden, password can be retrieved via
|
||||||
|
@ -12,6 +12,8 @@ _$_LocalAccount _$$_LocalAccountFromJson(Map<String, dynamic> json) =>
|
|||||||
json['identity_master'] as Map<String, dynamic>),
|
json['identity_master'] as Map<String, dynamic>),
|
||||||
identitySecretKeyBytes: const Uint8ListJsonConverter()
|
identitySecretKeyBytes: const Uint8ListJsonConverter()
|
||||||
.fromJson(json['identity_secret_key_bytes'] as String),
|
.fromJson(json['identity_secret_key_bytes'] as String),
|
||||||
|
identitySecretSaltBytes: const Uint8ListJsonConverter()
|
||||||
|
.fromJson(json['identity_secret_salt_bytes'] as String),
|
||||||
encryptionKeyType:
|
encryptionKeyType:
|
||||||
EncryptionKeyType.fromJson(json['encryption_key_type'] as String),
|
EncryptionKeyType.fromJson(json['encryption_key_type'] as String),
|
||||||
biometricsEnabled: json['biometrics_enabled'] as bool,
|
biometricsEnabled: json['biometrics_enabled'] as bool,
|
||||||
@ -23,6 +25,8 @@ Map<String, dynamic> _$$_LocalAccountToJson(_$_LocalAccount instance) =>
|
|||||||
'identity_master': instance.identityMaster.toJson(),
|
'identity_master': instance.identityMaster.toJson(),
|
||||||
'identity_secret_key_bytes': const Uint8ListJsonConverter()
|
'identity_secret_key_bytes': const Uint8ListJsonConverter()
|
||||||
.toJson(instance.identitySecretKeyBytes),
|
.toJson(instance.identitySecretKeyBytes),
|
||||||
|
'identity_secret_salt_bytes': const Uint8ListJsonConverter()
|
||||||
|
.toJson(instance.identitySecretSaltBytes),
|
||||||
'encryption_key_type': instance.encryptionKeyType.toJson(),
|
'encryption_key_type': instance.encryptionKeyType.toJson(),
|
||||||
'biometrics_enabled': instance.biometricsEnabled,
|
'biometrics_enabled': instance.biometricsEnabled,
|
||||||
'hidden_account': instance.hiddenAccount,
|
'hidden_account': instance.hiddenAccount,
|
||||||
|
@ -1 +1,126 @@
|
|||||||
export 'proto/veilidchat.pb.dart';
|
export 'proto/veilidchat.pb.dart';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:veilid/veilid.dart';
|
||||||
|
|
||||||
|
import 'proto/veilidchat.pb.dart' as proto;
|
||||||
|
|
||||||
|
/// CryptoKey protobuf marshaling
|
||||||
|
///
|
||||||
|
extension CryptoKeyProto on CryptoKey {
|
||||||
|
proto.CryptoKey toProto() {
|
||||||
|
final b = decode();
|
||||||
|
final out = proto.CryptoKey();
|
||||||
|
out.u0 = b[0];
|
||||||
|
out.u1 = b[1];
|
||||||
|
out.u2 = b[2];
|
||||||
|
out.u3 = b[3];
|
||||||
|
out.u4 = b[4];
|
||||||
|
out.u5 = b[5];
|
||||||
|
out.u6 = b[6];
|
||||||
|
out.u7 = b[7];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CryptoKey fromProto(proto.CryptoKey p) {
|
||||||
|
final b = Uint8List(8);
|
||||||
|
b[0] = p.u0;
|
||||||
|
b[1] = p.u1;
|
||||||
|
b[2] = p.u2;
|
||||||
|
b[3] = p.u3;
|
||||||
|
b[4] = p.u4;
|
||||||
|
b[5] = p.u5;
|
||||||
|
b[6] = p.u6;
|
||||||
|
b[7] = p.u7;
|
||||||
|
return CryptoKey.fromBytes(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Signature protobuf marshaling
|
||||||
|
///
|
||||||
|
extension SignatureProto on Signature {
|
||||||
|
proto.Signature toProto() {
|
||||||
|
final b = decode();
|
||||||
|
final out = proto.Signature();
|
||||||
|
out.u0 = b[0];
|
||||||
|
out.u1 = b[1];
|
||||||
|
out.u2 = b[2];
|
||||||
|
out.u3 = b[3];
|
||||||
|
out.u4 = b[4];
|
||||||
|
out.u5 = b[5];
|
||||||
|
out.u6 = b[6];
|
||||||
|
out.u7 = b[7];
|
||||||
|
out.u8 = b[8];
|
||||||
|
out.u9 = b[9];
|
||||||
|
out.u10 = b[10];
|
||||||
|
out.u11 = b[11];
|
||||||
|
out.u12 = b[12];
|
||||||
|
out.u13 = b[13];
|
||||||
|
out.u14 = b[14];
|
||||||
|
out.u15 = b[15];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Signature fromProto(proto.Signature p) {
|
||||||
|
final b = Uint8List(16);
|
||||||
|
b[0] = p.u0;
|
||||||
|
b[1] = p.u1;
|
||||||
|
b[2] = p.u2;
|
||||||
|
b[3] = p.u3;
|
||||||
|
b[4] = p.u4;
|
||||||
|
b[5] = p.u5;
|
||||||
|
b[6] = p.u6;
|
||||||
|
b[7] = p.u7;
|
||||||
|
b[8] = p.u8;
|
||||||
|
b[9] = p.u9;
|
||||||
|
b[10] = p.u10;
|
||||||
|
b[11] = p.u11;
|
||||||
|
b[12] = p.u12;
|
||||||
|
b[13] = p.u13;
|
||||||
|
b[14] = p.u14;
|
||||||
|
b[15] = p.u15;
|
||||||
|
return Signature.fromBytes(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Nonce protobuf marshaling
|
||||||
|
///
|
||||||
|
extension NonceProto on Nonce {
|
||||||
|
proto.Signature toProto() {
|
||||||
|
final b = decode();
|
||||||
|
final out = proto.Signature();
|
||||||
|
out.u0 = b[0];
|
||||||
|
out.u1 = b[1];
|
||||||
|
out.u2 = b[2];
|
||||||
|
out.u3 = b[3];
|
||||||
|
out.u4 = b[4];
|
||||||
|
out.u5 = b[5];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Nonce fromProto(proto.Nonce p) {
|
||||||
|
final b = Uint8List(6);
|
||||||
|
b[0] = p.u0;
|
||||||
|
b[1] = p.u1;
|
||||||
|
b[2] = p.u2;
|
||||||
|
b[3] = p.u3;
|
||||||
|
b[4] = p.u4;
|
||||||
|
b[5] = p.u5;
|
||||||
|
return Nonce.fromBytes(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TypedKey protobuf marshaling
|
||||||
|
///
|
||||||
|
extension TypedKeyProto on TypedKey {
|
||||||
|
proto.TypedKey toProto() {
|
||||||
|
final out = proto.TypedKey();
|
||||||
|
out.kind = kind;
|
||||||
|
out.value = value.toProto();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TypedKey fromProto(proto.TypedKey p) {
|
||||||
|
return TypedKey(kind: p.kind, value: CryptoKeyProto.fromProto(p.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import 'dart:typed_data';
|
|||||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:veilid/veilid.dart';
|
import 'package:veilid/veilid.dart';
|
||||||
|
import 'package:veilidchat/tools/tools.dart';
|
||||||
|
|
||||||
import '../entities/entities.dart';
|
import '../entities/entities.dart';
|
||||||
import '../entities/proto.dart' as proto;
|
import '../entities/proto.dart' as proto;
|
||||||
@ -80,7 +81,7 @@ class LocalAccountManager {
|
|||||||
Uint8List.fromList(utf8.encode(jsonEncode(identityMaster)));
|
Uint8List.fromList(utf8.encode(jsonEncode(identityMaster)));
|
||||||
await dhtctx.setDHTValue(masterRecordKey, 0, identityMasterBytes);
|
await dhtctx.setDHTValue(masterRecordKey, 0, identityMasterBytes);
|
||||||
|
|
||||||
// Write empty identity to account map
|
// Write empty identity to identity dht key
|
||||||
const identity = Identity(accountKeyPairs: {});
|
const identity = Identity(accountKeyPairs: {});
|
||||||
final identityBytes =
|
final identityBytes =
|
||||||
Uint8List.fromList(utf8.encode(jsonEncode(identity)));
|
Uint8List.fromList(utf8.encode(jsonEncode(identity)));
|
||||||
@ -101,12 +102,32 @@ class LocalAccountManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> updateIdentityKey(
|
||||||
|
VeilidRoutingContext dhtctx,
|
||||||
|
TypedKey identityRecordKey,
|
||||||
|
TypedKey accountRecordKey,
|
||||||
|
KeyPair accountRecordOwner) async {
|
||||||
|
// Get existing identity key
|
||||||
|
ValueData? identityValueData =
|
||||||
|
await dhtctx.getDHTValue(identityRecordKey, 0, true);
|
||||||
|
if (identityValueData == null) {
|
||||||
|
throw const FormatException("Identity does not exist");
|
||||||
|
}
|
||||||
|
var identity = identityValueData.readJsonData(Identity.fromJson);
|
||||||
|
xxx make back to bytes function and do update loop and maybe make that a tool function too (consistentUpdate)
|
||||||
|
// Update identity key to include account
|
||||||
|
const identity = Identity(accountKeyPairs: {});
|
||||||
|
final identityBytes = Uint8List.fromList(utf8.encode(jsonEncode(identity)));
|
||||||
|
await dhtctx.setDHTValue(identityRec.key, 0, identityBytes);
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new account associated with master identity
|
/// Creates a new account associated with master identity
|
||||||
Future<LocalAccount> newAccount(
|
Future<LocalAccount> newAccount(
|
||||||
IdentityMaster identityMaster,
|
IdentityMaster identityMaster,
|
||||||
SecretKey identitySecret,
|
SecretKey identitySecret,
|
||||||
EncryptionKeyType encryptionKeyType,
|
EncryptionKeyType encryptionKeyType,
|
||||||
String encryptionKey) async {
|
String encryptionKey,
|
||||||
|
proto.Account account) async {
|
||||||
// Encrypt identitySecret with key
|
// Encrypt identitySecret with key
|
||||||
final cs = await Veilid.instance.bestCryptoSystem();
|
final cs = await Veilid.instance.bestCryptoSystem();
|
||||||
final ekbytes = Uint8List.fromList(utf8.encode(encryptionKey));
|
final ekbytes = Uint8List.fromList(utf8.encode(encryptionKey));
|
||||||
@ -126,7 +147,39 @@ class LocalAccountManager {
|
|||||||
hiddenAccount: false,
|
hiddenAccount: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Push
|
// Add account with profile to DHT
|
||||||
|
final dhtctx = (await Veilid.instance.routingContext())
|
||||||
|
.withPrivacy()
|
||||||
|
.withSequencing(Sequencing.ensureOrdered);
|
||||||
|
DHTRecordDescriptor? identityRec;
|
||||||
|
DHTRecordDescriptor? accountRec;
|
||||||
|
try {
|
||||||
|
identityRec = await dhtctx.openDHTRecord(identityMaster.identityRecordKey,
|
||||||
|
identityMaster.identityWriter(identitySecret));
|
||||||
|
accountRec = await dhtctx.createDHTRecord(const DHTSchema.dflt(oCnt: 1));
|
||||||
|
final crypto = await Veilid.instance.bestCryptoSystem();
|
||||||
|
assert(identityRec.key.kind == crypto.kind());
|
||||||
|
assert(accountRec.key.kind == crypto.kind());
|
||||||
|
|
||||||
|
// Write account key
|
||||||
|
assert(await dhtctx.setDHTValue(
|
||||||
|
accountRec.key, 0, account.writeToBuffer()) ==
|
||||||
|
null);
|
||||||
|
|
||||||
|
// Update identity key to include account
|
||||||
|
await updateIdentityKey(dhtctx, identityRec.key, accountRec.key,
|
||||||
|
KeyPair(key: accountRec.owner, secret: accountRec.ownerSecret!));
|
||||||
|
} catch (e) {
|
||||||
|
if (identityRec != null) {
|
||||||
|
await dhtctx.closeDHTRecord(identityRec.key);
|
||||||
|
}
|
||||||
|
if (accountRec != null) {
|
||||||
|
await dhtctx.deleteDHTRecord(accountRec.key);
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add local account object to internal store
|
||||||
|
|
||||||
// Return local account object
|
// Return local account object
|
||||||
return localAccount;
|
return localAccount;
|
||||||
|
@ -1 +1,9 @@
|
|||||||
export 'external_stream_state.dart';
|
export 'external_stream_state.dart';
|
||||||
|
import 'package:veilid/veilid.dart';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
extension FromValueDataJsonExt on ValueData {
|
||||||
|
T readJsonData<T>(T Function(Map<String, dynamic>) fromJson) {
|
||||||
|
return fromJson(jsonDecode(utf8.decode(data)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
34
pubspec.lock
34
pubspec.lock
@ -361,18 +361,18 @@ packages:
|
|||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: freezed
|
name: freezed
|
||||||
sha256: a9520490532087cf38bf3f7de478ab6ebeb5f68bb1eb2641546d92719b224445
|
sha256: "2df89855fe181baae3b6d714dc3c4317acf4fccd495a6f36e5e00f24144c6c3b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.5"
|
version: "2.4.1"
|
||||||
freezed_annotation:
|
freezed_annotation:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: freezed_annotation
|
name: freezed_annotation
|
||||||
sha256: aeac15850ef1b38ee368d4c53ba9a847e900bb2c53a4db3f6881cbb3cb684338
|
sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.4.1"
|
||||||
frontend_server_client:
|
frontend_server_client:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -401,10 +401,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: go_router
|
name: go_router
|
||||||
sha256: df5bc28ec7d2e2a82ece59fb33b3a0f3b3eaaae386bf32040f92339820d954b6
|
sha256: b33a88c67816312597e5e0f5906c5139a0b9bd9bb137346e872c788da7af8ea0
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.0.1"
|
version: "9.0.3"
|
||||||
graphs:
|
graphs:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -569,10 +569,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3"
|
sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.3"
|
version: "2.2.4"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -621,14 +621,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.1"
|
version: "1.5.1"
|
||||||
process:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: process
|
|
||||||
sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "4.2.4"
|
|
||||||
protobuf:
|
protobuf:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -721,10 +713,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_foundation
|
name: shared_preferences_foundation
|
||||||
sha256: "0dc5c49ad8a05ed358b991b60c7b0ba1a14e16dae58af9b420d6b9e82dc024ab"
|
sha256: f39696b83e844923b642ce9dd4bd31736c17e697f6731a5adf445b1274cf3cd4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.2"
|
||||||
shared_preferences_linux:
|
shared_preferences_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -912,7 +904,7 @@ packages:
|
|||||||
path: "../veilid/veilid-flutter"
|
path: "../veilid/veilid-flutter"
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.0.1"
|
version: "0.1.1"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -941,10 +933,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
|
sha256: e0b1147eec179d3911f1f19b59206448f78195ca1d20514134e10641b7d7fbff
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.1"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
Loading…
Reference in New Issue
Block a user