mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2024-12-24 07:09:29 -05:00
invitation work
This commit is contained in:
parent
96e3251b3b
commit
bb8a3df281
47
doc/invitations.md
Normal file
47
doc/invitations.md
Normal file
@ -0,0 +1,47 @@
|
||||
## Sending an invitation
|
||||
1. Generate writer keypair to share with new contact
|
||||
2. Encrypt secret with requested encryption type
|
||||
3. Create Local Chat DHT record (no content yet, will be encrypted with DH of contact identity key)
|
||||
4. Create ContactRequestPrivate and encrypt with the writer secret
|
||||
5. Create ContactRequest and embed possibly encrypted ContactRequestPrivate
|
||||
6. Create DHT unicast inbox for ContactRequest and store ContactRequest in owner subkey
|
||||
7. Create ContactInvitation and add invitation record to local table
|
||||
8. Create SignedContactInvitation embedding ContactInvitation
|
||||
9. Render SignedContactInvitation to shareable encoding (qr code, text blob, etc)
|
||||
10. Share SignedContactInvitation out of band to desired contact, along with password somehow if used
|
||||
|
||||
## Receiving an invitation
|
||||
1. Receive SignedContactInvitation from out of band, and the password somehow if used
|
||||
2. Get the ContactRequest record unicastinbox DHT record owner subkey from the network
|
||||
3. Decrypt the writer secret with the password if necessary
|
||||
4. Decrypt the ContactRequestPrivate chunk with the writer secret
|
||||
5. Get the contact's AccountMaster record key
|
||||
6. Verify identity signature on the SignedContactInvitation
|
||||
7. Verify expiration
|
||||
8. Display the profile and ask if the user wants to accept or reject the invitation
|
||||
|
||||
## Accepting an invitation
|
||||
1. Create a Local Chat DHT record (no content yet, will be encrypted with DH of contact identity key)
|
||||
2. Create ContactAccept with chat dht record and account master
|
||||
3. Create SignedContactResponse with accept=true signed with identity
|
||||
4. Set ContactRequest unicastinbox DHT record writer subkey with SignedContactResponse, encrypted with writer secret
|
||||
5. Add a local contact with the remote chat dht record, updating from the remote profile in it
|
||||
|
||||
## Rejecting an invitation
|
||||
1. Create ContactReject with account master
|
||||
2. Create SignedContactResponse with accept=false signed with identity
|
||||
3. Set ContactRequest unicastinbox DHT record writer subkey with SignedContactResponse, encrypted with writer secret
|
||||
|
||||
## Receiving an accept/reject
|
||||
1. Decrypt with writer secret
|
||||
2. Get DHT record for contact's AccountMaster
|
||||
3. Validate the SignedContactResponse signature
|
||||
|
||||
If accept == false:
|
||||
1. Announce rejection
|
||||
2. Delete local invitation from table
|
||||
|
||||
If accept == true:
|
||||
1. Add a local contact with the remote chat dht record, updating from the remote profile in it.
|
||||
2. Delete local invitation from table
|
||||
|
@ -1122,6 +1122,7 @@ class Account extends $pb.GeneratedMessage {
|
||||
..aOB(2, _omitFieldNames ? '' : 'invisible')
|
||||
..a<$core.int>(3, _omitFieldNames ? '' : 'autoAwayTimeoutSec', $pb.PbFieldType.OU3)
|
||||
..aOM<TypedKey>(4, _omitFieldNames ? '' : 'contactList', subBuilder: TypedKey.create)
|
||||
..aOM<TypedKey>(5, _omitFieldNames ? '' : 'contactRequests', subBuilder: TypedKey.create)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@ -1185,6 +1186,497 @@ class Account extends $pb.GeneratedMessage {
|
||||
void clearContactList() => clearField(4);
|
||||
@$pb.TagNumber(4)
|
||||
TypedKey ensureContactList() => $_ensure(3);
|
||||
|
||||
@$pb.TagNumber(5)
|
||||
TypedKey get contactRequests => $_getN(4);
|
||||
@$pb.TagNumber(5)
|
||||
set contactRequests(TypedKey v) { setField(5, v); }
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasContactRequests() => $_has(4);
|
||||
@$pb.TagNumber(5)
|
||||
void clearContactRequests() => clearField(5);
|
||||
@$pb.TagNumber(5)
|
||||
TypedKey ensureContactRequests() => $_ensure(4);
|
||||
}
|
||||
|
||||
class ContactInvitation extends $pb.GeneratedMessage {
|
||||
factory ContactInvitation() => create();
|
||||
ContactInvitation._() : super();
|
||||
factory ContactInvitation.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory ContactInvitation.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ContactInvitation', createEmptyInstance: create)
|
||||
..aOM<TypedKey>(1, _omitFieldNames ? '' : 'contactRequestRecordKey', subBuilder: TypedKey.create)
|
||||
..a<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'writerSecret', $pb.PbFieldType.OY)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||
'Will be removed in next major version')
|
||||
ContactInvitation clone() => ContactInvitation()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
ContactInvitation copyWith(void Function(ContactInvitation) updates) => super.copyWith((message) => updates(message as ContactInvitation)) as ContactInvitation;
|
||||
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ContactInvitation create() => ContactInvitation._();
|
||||
ContactInvitation createEmptyInstance() => create();
|
||||
static $pb.PbList<ContactInvitation> createRepeated() => $pb.PbList<ContactInvitation>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ContactInvitation getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ContactInvitation>(create);
|
||||
static ContactInvitation? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
TypedKey get contactRequestRecordKey => $_getN(0);
|
||||
@$pb.TagNumber(1)
|
||||
set contactRequestRecordKey(TypedKey v) { setField(1, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasContactRequestRecordKey() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearContactRequestRecordKey() => clearField(1);
|
||||
@$pb.TagNumber(1)
|
||||
TypedKey ensureContactRequestRecordKey() => $_ensure(0);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.List<$core.int> get writerSecret => $_getN(1);
|
||||
@$pb.TagNumber(2)
|
||||
set writerSecret($core.List<$core.int> v) { $_setBytes(1, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasWriterSecret() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearWriterSecret() => clearField(2);
|
||||
}
|
||||
|
||||
class SignedContactInvitation extends $pb.GeneratedMessage {
|
||||
factory SignedContactInvitation() => create();
|
||||
SignedContactInvitation._() : super();
|
||||
factory SignedContactInvitation.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory SignedContactInvitation.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'SignedContactInvitation', createEmptyInstance: create)
|
||||
..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'contactInvitation', $pb.PbFieldType.OY)
|
||||
..aOM<Signature>(2, _omitFieldNames ? '' : 'identitySignature', subBuilder: Signature.create)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||
'Will be removed in next major version')
|
||||
SignedContactInvitation clone() => SignedContactInvitation()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
SignedContactInvitation copyWith(void Function(SignedContactInvitation) updates) => super.copyWith((message) => updates(message as SignedContactInvitation)) as SignedContactInvitation;
|
||||
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SignedContactInvitation create() => SignedContactInvitation._();
|
||||
SignedContactInvitation createEmptyInstance() => create();
|
||||
static $pb.PbList<SignedContactInvitation> createRepeated() => $pb.PbList<SignedContactInvitation>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SignedContactInvitation getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SignedContactInvitation>(create);
|
||||
static SignedContactInvitation? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.List<$core.int> get contactInvitation => $_getN(0);
|
||||
@$pb.TagNumber(1)
|
||||
set contactInvitation($core.List<$core.int> v) { $_setBytes(0, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasContactInvitation() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearContactInvitation() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
Signature get identitySignature => $_getN(1);
|
||||
@$pb.TagNumber(2)
|
||||
set identitySignature(Signature v) { setField(2, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasIdentitySignature() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearIdentitySignature() => clearField(2);
|
||||
@$pb.TagNumber(2)
|
||||
Signature ensureIdentitySignature() => $_ensure(1);
|
||||
}
|
||||
|
||||
class ContactRequest extends $pb.GeneratedMessage {
|
||||
factory ContactRequest() => create();
|
||||
ContactRequest._() : super();
|
||||
factory ContactRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory ContactRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ContactRequest', createEmptyInstance: create)
|
||||
..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'writerSalt', $pb.PbFieldType.OY)
|
||||
..e<EncryptionKind>(2, _omitFieldNames ? '' : 'encryptionKeyType', $pb.PbFieldType.OE, defaultOrMaker: EncryptionKind.ENCRYPTION_KIND_UNSPECIFIED, valueOf: EncryptionKind.valueOf, enumValues: EncryptionKind.values)
|
||||
..a<$core.List<$core.int>>(3, _omitFieldNames ? '' : 'private', $pb.PbFieldType.OY)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||
'Will be removed in next major version')
|
||||
ContactRequest clone() => ContactRequest()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
ContactRequest copyWith(void Function(ContactRequest) updates) => super.copyWith((message) => updates(message as ContactRequest)) as ContactRequest;
|
||||
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ContactRequest create() => ContactRequest._();
|
||||
ContactRequest createEmptyInstance() => create();
|
||||
static $pb.PbList<ContactRequest> createRepeated() => $pb.PbList<ContactRequest>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ContactRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ContactRequest>(create);
|
||||
static ContactRequest? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.List<$core.int> get writerSalt => $_getN(0);
|
||||
@$pb.TagNumber(1)
|
||||
set writerSalt($core.List<$core.int> v) { $_setBytes(0, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasWriterSalt() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearWriterSalt() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
EncryptionKind get encryptionKeyType => $_getN(1);
|
||||
@$pb.TagNumber(2)
|
||||
set encryptionKeyType(EncryptionKind v) { setField(2, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasEncryptionKeyType() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearEncryptionKeyType() => clearField(2);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
$core.List<$core.int> get private => $_getN(2);
|
||||
@$pb.TagNumber(3)
|
||||
set private($core.List<$core.int> v) { $_setBytes(2, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasPrivate() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearPrivate() => clearField(3);
|
||||
}
|
||||
|
||||
class ContactRequestPrivate extends $pb.GeneratedMessage {
|
||||
factory ContactRequestPrivate() => create();
|
||||
ContactRequestPrivate._() : super();
|
||||
factory ContactRequestPrivate.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory ContactRequestPrivate.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ContactRequestPrivate', createEmptyInstance: create)
|
||||
..aOM<CryptoKey>(1, _omitFieldNames ? '' : 'writerKey', subBuilder: CryptoKey.create)
|
||||
..aOM<Profile>(2, _omitFieldNames ? '' : 'profile', subBuilder: Profile.create)
|
||||
..aOM<TypedKey>(3, _omitFieldNames ? '' : 'accountMasterRecordKey', subBuilder: TypedKey.create)
|
||||
..aOM<TypedKey>(4, _omitFieldNames ? '' : 'chatRecordKey', subBuilder: TypedKey.create)
|
||||
..a<$fixnum.Int64>(5, _omitFieldNames ? '' : 'expiration', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||
'Will be removed in next major version')
|
||||
ContactRequestPrivate clone() => ContactRequestPrivate()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
ContactRequestPrivate copyWith(void Function(ContactRequestPrivate) updates) => super.copyWith((message) => updates(message as ContactRequestPrivate)) as ContactRequestPrivate;
|
||||
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ContactRequestPrivate create() => ContactRequestPrivate._();
|
||||
ContactRequestPrivate createEmptyInstance() => create();
|
||||
static $pb.PbList<ContactRequestPrivate> createRepeated() => $pb.PbList<ContactRequestPrivate>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ContactRequestPrivate getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ContactRequestPrivate>(create);
|
||||
static ContactRequestPrivate? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
CryptoKey get writerKey => $_getN(0);
|
||||
@$pb.TagNumber(1)
|
||||
set writerKey(CryptoKey v) { setField(1, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasWriterKey() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearWriterKey() => clearField(1);
|
||||
@$pb.TagNumber(1)
|
||||
CryptoKey ensureWriterKey() => $_ensure(0);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
Profile get profile => $_getN(1);
|
||||
@$pb.TagNumber(2)
|
||||
set profile(Profile v) { setField(2, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasProfile() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearProfile() => clearField(2);
|
||||
@$pb.TagNumber(2)
|
||||
Profile ensureProfile() => $_ensure(1);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
TypedKey get accountMasterRecordKey => $_getN(2);
|
||||
@$pb.TagNumber(3)
|
||||
set accountMasterRecordKey(TypedKey v) { setField(3, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasAccountMasterRecordKey() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearAccountMasterRecordKey() => clearField(3);
|
||||
@$pb.TagNumber(3)
|
||||
TypedKey ensureAccountMasterRecordKey() => $_ensure(2);
|
||||
|
||||
@$pb.TagNumber(4)
|
||||
TypedKey get chatRecordKey => $_getN(3);
|
||||
@$pb.TagNumber(4)
|
||||
set chatRecordKey(TypedKey v) { setField(4, v); }
|
||||
@$pb.TagNumber(4)
|
||||
$core.bool hasChatRecordKey() => $_has(3);
|
||||
@$pb.TagNumber(4)
|
||||
void clearChatRecordKey() => clearField(4);
|
||||
@$pb.TagNumber(4)
|
||||
TypedKey ensureChatRecordKey() => $_ensure(3);
|
||||
|
||||
@$pb.TagNumber(5)
|
||||
$fixnum.Int64 get expiration => $_getI64(4);
|
||||
@$pb.TagNumber(5)
|
||||
set expiration($fixnum.Int64 v) { $_setInt64(4, v); }
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasExpiration() => $_has(4);
|
||||
@$pb.TagNumber(5)
|
||||
void clearExpiration() => clearField(5);
|
||||
}
|
||||
|
||||
class ContactResponse extends $pb.GeneratedMessage {
|
||||
factory ContactResponse() => create();
|
||||
ContactResponse._() : super();
|
||||
factory ContactResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory ContactResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ContactResponse', createEmptyInstance: create)
|
||||
..aOB(1, _omitFieldNames ? '' : 'accept')
|
||||
..aOM<TypedKey>(2, _omitFieldNames ? '' : 'accountMasterRecordKey', subBuilder: TypedKey.create)
|
||||
..aOM<TypedKey>(3, _omitFieldNames ? '' : 'chatRecordKey', subBuilder: TypedKey.create)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||
'Will be removed in next major version')
|
||||
ContactResponse clone() => ContactResponse()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
ContactResponse copyWith(void Function(ContactResponse) updates) => super.copyWith((message) => updates(message as ContactResponse)) as ContactResponse;
|
||||
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ContactResponse create() => ContactResponse._();
|
||||
ContactResponse createEmptyInstance() => create();
|
||||
static $pb.PbList<ContactResponse> createRepeated() => $pb.PbList<ContactResponse>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ContactResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ContactResponse>(create);
|
||||
static ContactResponse? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool get accept => $_getBF(0);
|
||||
@$pb.TagNumber(1)
|
||||
set accept($core.bool v) { $_setBool(0, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasAccept() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearAccept() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
TypedKey get accountMasterRecordKey => $_getN(1);
|
||||
@$pb.TagNumber(2)
|
||||
set accountMasterRecordKey(TypedKey v) { setField(2, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasAccountMasterRecordKey() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearAccountMasterRecordKey() => clearField(2);
|
||||
@$pb.TagNumber(2)
|
||||
TypedKey ensureAccountMasterRecordKey() => $_ensure(1);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
TypedKey get chatRecordKey => $_getN(2);
|
||||
@$pb.TagNumber(3)
|
||||
set chatRecordKey(TypedKey v) { setField(3, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasChatRecordKey() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearChatRecordKey() => clearField(3);
|
||||
@$pb.TagNumber(3)
|
||||
TypedKey ensureChatRecordKey() => $_ensure(2);
|
||||
}
|
||||
|
||||
class SignedContactResponse extends $pb.GeneratedMessage {
|
||||
factory SignedContactResponse() => create();
|
||||
SignedContactResponse._() : super();
|
||||
factory SignedContactResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory SignedContactResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'SignedContactResponse', createEmptyInstance: create)
|
||||
..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'contactResponse', $pb.PbFieldType.OY)
|
||||
..aOM<Signature>(2, _omitFieldNames ? '' : 'identitySignature', subBuilder: Signature.create)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||
'Will be removed in next major version')
|
||||
SignedContactResponse clone() => SignedContactResponse()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
SignedContactResponse copyWith(void Function(SignedContactResponse) updates) => super.copyWith((message) => updates(message as SignedContactResponse)) as SignedContactResponse;
|
||||
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SignedContactResponse create() => SignedContactResponse._();
|
||||
SignedContactResponse createEmptyInstance() => create();
|
||||
static $pb.PbList<SignedContactResponse> createRepeated() => $pb.PbList<SignedContactResponse>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SignedContactResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SignedContactResponse>(create);
|
||||
static SignedContactResponse? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.List<$core.int> get contactResponse => $_getN(0);
|
||||
@$pb.TagNumber(1)
|
||||
set contactResponse($core.List<$core.int> v) { $_setBytes(0, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasContactResponse() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearContactResponse() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
Signature get identitySignature => $_getN(1);
|
||||
@$pb.TagNumber(2)
|
||||
set identitySignature(Signature v) { setField(2, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasIdentitySignature() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearIdentitySignature() => clearField(2);
|
||||
@$pb.TagNumber(2)
|
||||
Signature ensureIdentitySignature() => $_ensure(1);
|
||||
}
|
||||
|
||||
class ContactRequestRecord extends $pb.GeneratedMessage {
|
||||
factory ContactRequestRecord() => create();
|
||||
ContactRequestRecord._() : super();
|
||||
factory ContactRequestRecord.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory ContactRequestRecord.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ContactRequestRecord', createEmptyInstance: create)
|
||||
..aOM<TypedKey>(1, _omitFieldNames ? '' : 'contactRequestRecordKey', subBuilder: TypedKey.create)
|
||||
..aOM<CryptoKey>(2, _omitFieldNames ? '' : 'writerKey', subBuilder: CryptoKey.create)
|
||||
..aOM<CryptoKey>(3, _omitFieldNames ? '' : 'writerSecret', subBuilder: CryptoKey.create)
|
||||
..aOM<TypedKey>(4, _omitFieldNames ? '' : 'chatRecordKey', subBuilder: TypedKey.create)
|
||||
..a<$fixnum.Int64>(5, _omitFieldNames ? '' : 'expiration', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO)
|
||||
..a<$core.List<$core.int>>(6, _omitFieldNames ? '' : 'invitation', $pb.PbFieldType.OY)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||
'Will be removed in next major version')
|
||||
ContactRequestRecord clone() => ContactRequestRecord()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
ContactRequestRecord copyWith(void Function(ContactRequestRecord) updates) => super.copyWith((message) => updates(message as ContactRequestRecord)) as ContactRequestRecord;
|
||||
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ContactRequestRecord create() => ContactRequestRecord._();
|
||||
ContactRequestRecord createEmptyInstance() => create();
|
||||
static $pb.PbList<ContactRequestRecord> createRepeated() => $pb.PbList<ContactRequestRecord>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ContactRequestRecord getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ContactRequestRecord>(create);
|
||||
static ContactRequestRecord? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
TypedKey get contactRequestRecordKey => $_getN(0);
|
||||
@$pb.TagNumber(1)
|
||||
set contactRequestRecordKey(TypedKey v) { setField(1, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasContactRequestRecordKey() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearContactRequestRecordKey() => clearField(1);
|
||||
@$pb.TagNumber(1)
|
||||
TypedKey ensureContactRequestRecordKey() => $_ensure(0);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
CryptoKey get writerKey => $_getN(1);
|
||||
@$pb.TagNumber(2)
|
||||
set writerKey(CryptoKey v) { setField(2, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasWriterKey() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearWriterKey() => clearField(2);
|
||||
@$pb.TagNumber(2)
|
||||
CryptoKey ensureWriterKey() => $_ensure(1);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
CryptoKey get writerSecret => $_getN(2);
|
||||
@$pb.TagNumber(3)
|
||||
set writerSecret(CryptoKey v) { setField(3, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasWriterSecret() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearWriterSecret() => clearField(3);
|
||||
@$pb.TagNumber(3)
|
||||
CryptoKey ensureWriterSecret() => $_ensure(2);
|
||||
|
||||
@$pb.TagNumber(4)
|
||||
TypedKey get chatRecordKey => $_getN(3);
|
||||
@$pb.TagNumber(4)
|
||||
set chatRecordKey(TypedKey v) { setField(4, v); }
|
||||
@$pb.TagNumber(4)
|
||||
$core.bool hasChatRecordKey() => $_has(3);
|
||||
@$pb.TagNumber(4)
|
||||
void clearChatRecordKey() => clearField(4);
|
||||
@$pb.TagNumber(4)
|
||||
TypedKey ensureChatRecordKey() => $_ensure(3);
|
||||
|
||||
@$pb.TagNumber(5)
|
||||
$fixnum.Int64 get expiration => $_getI64(4);
|
||||
@$pb.TagNumber(5)
|
||||
set expiration($fixnum.Int64 v) { $_setInt64(4, v); }
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasExpiration() => $_has(4);
|
||||
@$pb.TagNumber(5)
|
||||
void clearExpiration() => clearField(5);
|
||||
|
||||
@$pb.TagNumber(6)
|
||||
$core.List<$core.int> get invitation => $_getN(5);
|
||||
@$pb.TagNumber(6)
|
||||
set invitation($core.List<$core.int> v) { $_setBytes(5, v); }
|
||||
@$pb.TagNumber(6)
|
||||
$core.bool hasInvitation() => $_has(5);
|
||||
@$pb.TagNumber(6)
|
||||
void clearInvitation() => clearField(6);
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,5 +51,22 @@ class Availability extends $pb.ProtobufEnum {
|
||||
const Availability._($core.int v, $core.String n) : super(v, n);
|
||||
}
|
||||
|
||||
class EncryptionKind extends $pb.ProtobufEnum {
|
||||
static const EncryptionKind ENCRYPTION_KIND_UNSPECIFIED = EncryptionKind._(0, _omitEnumNames ? '' : 'ENCRYPTION_KIND_UNSPECIFIED');
|
||||
static const EncryptionKind ENCRYPTION_KIND_PIN = EncryptionKind._(1, _omitEnumNames ? '' : 'ENCRYPTION_KIND_PIN');
|
||||
static const EncryptionKind ENCRYPTION_KIND_PASSWORD = EncryptionKind._(2, _omitEnumNames ? '' : 'ENCRYPTION_KIND_PASSWORD');
|
||||
|
||||
static const $core.List<EncryptionKind> values = <EncryptionKind> [
|
||||
ENCRYPTION_KIND_UNSPECIFIED,
|
||||
ENCRYPTION_KIND_PIN,
|
||||
ENCRYPTION_KIND_PASSWORD,
|
||||
];
|
||||
|
||||
static final $core.Map<$core.int, EncryptionKind> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||
static EncryptionKind? valueOf($core.int value) => _byValue[value];
|
||||
|
||||
const EncryptionKind._($core.int v, $core.String n) : super(v, n);
|
||||
}
|
||||
|
||||
|
||||
const _omitEnumNames = $core.bool.fromEnvironment('protobuf.omit_enum_names');
|
||||
|
@ -46,6 +46,21 @@ final $typed_data.Uint8List availabilityDescriptor = $convert.base64Decode(
|
||||
'lMSVRZX09GRkxJTkUQARIVChFBVkFJTEFCSUxJVFlfRlJFRRACEhUKEUFWQUlMQUJJTElUWV9C'
|
||||
'VVNZEAMSFQoRQVZBSUxBQklMSVRZX0FXQVkQBA==');
|
||||
|
||||
@$core.Deprecated('Use encryptionKindDescriptor instead')
|
||||
const EncryptionKind$json = {
|
||||
'1': 'EncryptionKind',
|
||||
'2': [
|
||||
{'1': 'ENCRYPTION_KIND_UNSPECIFIED', '2': 0},
|
||||
{'1': 'ENCRYPTION_KIND_PIN', '2': 1},
|
||||
{'1': 'ENCRYPTION_KIND_PASSWORD', '2': 2},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `EncryptionKind`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||
final $typed_data.Uint8List encryptionKindDescriptor = $convert.base64Decode(
|
||||
'Cg5FbmNyeXB0aW9uS2luZBIfChtFTkNSWVBUSU9OX0tJTkRfVU5TUEVDSUZJRUQQABIXChNFTk'
|
||||
'NSWVBUSU9OX0tJTkRfUElOEAESHAoYRU5DUllQVElPTl9LSU5EX1BBU1NXT1JEEAI=');
|
||||
|
||||
@$core.Deprecated('Use cryptoKeyDescriptor instead')
|
||||
const CryptoKey$json = {
|
||||
'1': 'CryptoKey',
|
||||
@ -301,6 +316,7 @@ const Account$json = {
|
||||
{'1': 'invisible', '3': 2, '4': 1, '5': 8, '10': 'invisible'},
|
||||
{'1': 'auto_away_timeout_sec', '3': 3, '4': 1, '5': 13, '10': 'autoAwayTimeoutSec'},
|
||||
{'1': 'contact_list', '3': 4, '4': 1, '5': 11, '6': '.TypedKey', '10': 'contactList'},
|
||||
{'1': 'contact_requests', '3': 5, '4': 1, '5': 11, '6': '.TypedKey', '10': 'contactRequests'},
|
||||
],
|
||||
};
|
||||
|
||||
@ -309,5 +325,125 @@ final $typed_data.Uint8List accountDescriptor = $convert.base64Decode(
|
||||
'CgdBY2NvdW50EiIKB3Byb2ZpbGUYASABKAsyCC5Qcm9maWxlUgdwcm9maWxlEhwKCWludmlzaW'
|
||||
'JsZRgCIAEoCFIJaW52aXNpYmxlEjEKFWF1dG9fYXdheV90aW1lb3V0X3NlYxgDIAEoDVISYXV0'
|
||||
'b0F3YXlUaW1lb3V0U2VjEiwKDGNvbnRhY3RfbGlzdBgEIAEoCzIJLlR5cGVkS2V5Ugtjb250YW'
|
||||
'N0TGlzdA==');
|
||||
'N0TGlzdBI0ChBjb250YWN0X3JlcXVlc3RzGAUgASgLMgkuVHlwZWRLZXlSD2NvbnRhY3RSZXF1'
|
||||
'ZXN0cw==');
|
||||
|
||||
@$core.Deprecated('Use contactInvitationDescriptor instead')
|
||||
const ContactInvitation$json = {
|
||||
'1': 'ContactInvitation',
|
||||
'2': [
|
||||
{'1': 'contact_request_record_key', '3': 1, '4': 1, '5': 11, '6': '.TypedKey', '10': 'contactRequestRecordKey'},
|
||||
{'1': 'writer_secret', '3': 2, '4': 1, '5': 12, '10': 'writerSecret'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ContactInvitation`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List contactInvitationDescriptor = $convert.base64Decode(
|
||||
'ChFDb250YWN0SW52aXRhdGlvbhJGChpjb250YWN0X3JlcXVlc3RfcmVjb3JkX2tleRgBIAEoCz'
|
||||
'IJLlR5cGVkS2V5Uhdjb250YWN0UmVxdWVzdFJlY29yZEtleRIjCg13cml0ZXJfc2VjcmV0GAIg'
|
||||
'ASgMUgx3cml0ZXJTZWNyZXQ=');
|
||||
|
||||
@$core.Deprecated('Use signedContactInvitationDescriptor instead')
|
||||
const SignedContactInvitation$json = {
|
||||
'1': 'SignedContactInvitation',
|
||||
'2': [
|
||||
{'1': 'contact_invitation', '3': 1, '4': 1, '5': 12, '10': 'contactInvitation'},
|
||||
{'1': 'identity_signature', '3': 2, '4': 1, '5': 11, '6': '.Signature', '10': 'identitySignature'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `SignedContactInvitation`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List signedContactInvitationDescriptor = $convert.base64Decode(
|
||||
'ChdTaWduZWRDb250YWN0SW52aXRhdGlvbhItChJjb250YWN0X2ludml0YXRpb24YASABKAxSEW'
|
||||
'NvbnRhY3RJbnZpdGF0aW9uEjkKEmlkZW50aXR5X3NpZ25hdHVyZRgCIAEoCzIKLlNpZ25hdHVy'
|
||||
'ZVIRaWRlbnRpdHlTaWduYXR1cmU=');
|
||||
|
||||
@$core.Deprecated('Use contactRequestDescriptor instead')
|
||||
const ContactRequest$json = {
|
||||
'1': 'ContactRequest',
|
||||
'2': [
|
||||
{'1': 'writer_salt', '3': 1, '4': 1, '5': 12, '10': 'writerSalt'},
|
||||
{'1': 'encryption_key_type', '3': 2, '4': 1, '5': 14, '6': '.EncryptionKind', '10': 'encryptionKeyType'},
|
||||
{'1': 'private', '3': 3, '4': 1, '5': 12, '10': 'private'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ContactRequest`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List contactRequestDescriptor = $convert.base64Decode(
|
||||
'Cg5Db250YWN0UmVxdWVzdBIfCgt3cml0ZXJfc2FsdBgBIAEoDFIKd3JpdGVyU2FsdBI/ChNlbm'
|
||||
'NyeXB0aW9uX2tleV90eXBlGAIgASgOMg8uRW5jcnlwdGlvbktpbmRSEWVuY3J5cHRpb25LZXlU'
|
||||
'eXBlEhgKB3ByaXZhdGUYAyABKAxSB3ByaXZhdGU=');
|
||||
|
||||
@$core.Deprecated('Use contactRequestPrivateDescriptor instead')
|
||||
const ContactRequestPrivate$json = {
|
||||
'1': 'ContactRequestPrivate',
|
||||
'2': [
|
||||
{'1': 'writer_key', '3': 1, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'writerKey'},
|
||||
{'1': 'profile', '3': 2, '4': 1, '5': 11, '6': '.Profile', '10': 'profile'},
|
||||
{'1': 'account_master_record_key', '3': 3, '4': 1, '5': 11, '6': '.TypedKey', '10': 'accountMasterRecordKey'},
|
||||
{'1': 'chat_record_key', '3': 4, '4': 1, '5': 11, '6': '.TypedKey', '10': 'chatRecordKey'},
|
||||
{'1': 'expiration', '3': 5, '4': 1, '5': 4, '10': 'expiration'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ContactRequestPrivate`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List contactRequestPrivateDescriptor = $convert.base64Decode(
|
||||
'ChVDb250YWN0UmVxdWVzdFByaXZhdGUSKQoKd3JpdGVyX2tleRgBIAEoCzIKLkNyeXB0b0tleV'
|
||||
'IJd3JpdGVyS2V5EiIKB3Byb2ZpbGUYAiABKAsyCC5Qcm9maWxlUgdwcm9maWxlEkQKGWFjY291'
|
||||
'bnRfbWFzdGVyX3JlY29yZF9rZXkYAyABKAsyCS5UeXBlZEtleVIWYWNjb3VudE1hc3RlclJlY2'
|
||||
'9yZEtleRIxCg9jaGF0X3JlY29yZF9rZXkYBCABKAsyCS5UeXBlZEtleVINY2hhdFJlY29yZEtl'
|
||||
'eRIeCgpleHBpcmF0aW9uGAUgASgEUgpleHBpcmF0aW9u');
|
||||
|
||||
@$core.Deprecated('Use contactResponseDescriptor instead')
|
||||
const ContactResponse$json = {
|
||||
'1': 'ContactResponse',
|
||||
'2': [
|
||||
{'1': 'accept', '3': 1, '4': 1, '5': 8, '10': 'accept'},
|
||||
{'1': 'account_master_record_key', '3': 2, '4': 1, '5': 11, '6': '.TypedKey', '10': 'accountMasterRecordKey'},
|
||||
{'1': 'chat_record_key', '3': 3, '4': 1, '5': 11, '6': '.TypedKey', '10': 'chatRecordKey'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ContactResponse`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List contactResponseDescriptor = $convert.base64Decode(
|
||||
'Cg9Db250YWN0UmVzcG9uc2USFgoGYWNjZXB0GAEgASgIUgZhY2NlcHQSRAoZYWNjb3VudF9tYX'
|
||||
'N0ZXJfcmVjb3JkX2tleRgCIAEoCzIJLlR5cGVkS2V5UhZhY2NvdW50TWFzdGVyUmVjb3JkS2V5'
|
||||
'EjEKD2NoYXRfcmVjb3JkX2tleRgDIAEoCzIJLlR5cGVkS2V5Ug1jaGF0UmVjb3JkS2V5');
|
||||
|
||||
@$core.Deprecated('Use signedContactResponseDescriptor instead')
|
||||
const SignedContactResponse$json = {
|
||||
'1': 'SignedContactResponse',
|
||||
'2': [
|
||||
{'1': 'contact_response', '3': 1, '4': 1, '5': 12, '10': 'contactResponse'},
|
||||
{'1': 'identity_signature', '3': 2, '4': 1, '5': 11, '6': '.Signature', '10': 'identitySignature'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `SignedContactResponse`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List signedContactResponseDescriptor = $convert.base64Decode(
|
||||
'ChVTaWduZWRDb250YWN0UmVzcG9uc2USKQoQY29udGFjdF9yZXNwb25zZRgBIAEoDFIPY29udG'
|
||||
'FjdFJlc3BvbnNlEjkKEmlkZW50aXR5X3NpZ25hdHVyZRgCIAEoCzIKLlNpZ25hdHVyZVIRaWRl'
|
||||
'bnRpdHlTaWduYXR1cmU=');
|
||||
|
||||
@$core.Deprecated('Use contactRequestRecordDescriptor instead')
|
||||
const ContactRequestRecord$json = {
|
||||
'1': 'ContactRequestRecord',
|
||||
'2': [
|
||||
{'1': 'contact_request_record_key', '3': 1, '4': 1, '5': 11, '6': '.TypedKey', '10': 'contactRequestRecordKey'},
|
||||
{'1': 'writer_key', '3': 2, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'writerKey'},
|
||||
{'1': 'writer_secret', '3': 3, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'writerSecret'},
|
||||
{'1': 'chat_record_key', '3': 4, '4': 1, '5': 11, '6': '.TypedKey', '10': 'chatRecordKey'},
|
||||
{'1': 'expiration', '3': 5, '4': 1, '5': 4, '10': 'expiration'},
|
||||
{'1': 'invitation', '3': 6, '4': 1, '5': 12, '10': 'invitation'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ContactRequestRecord`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List contactRequestRecordDescriptor = $convert.base64Decode(
|
||||
'ChRDb250YWN0UmVxdWVzdFJlY29yZBJGChpjb250YWN0X3JlcXVlc3RfcmVjb3JkX2tleRgBIA'
|
||||
'EoCzIJLlR5cGVkS2V5Uhdjb250YWN0UmVxdWVzdFJlY29yZEtleRIpCgp3cml0ZXJfa2V5GAIg'
|
||||
'ASgLMgouQ3J5cHRvS2V5Ugl3cml0ZXJLZXkSLwoNd3JpdGVyX3NlY3JldBgDIAEoCzIKLkNyeX'
|
||||
'B0b0tleVIMd3JpdGVyU2VjcmV0EjEKD2NoYXRfcmVjb3JkX2tleRgEIAEoCzIJLlR5cGVkS2V5'
|
||||
'Ug1jaGF0UmVjb3JkS2V5Eh4KCmV4cGlyYXRpb24YBSABKARSCmV4cGlyYXRpb24SHgoKaW52aX'
|
||||
'RhdGlvbhgGIAEoDFIKaW52aXRhdGlvbg==');
|
||||
|
||||
|
@ -61,6 +61,7 @@ message TypedKey {
|
||||
|
||||
message DHTData {
|
||||
// Other keys to concatenate
|
||||
// Uses the same writer as this DHTList with SMPL schema
|
||||
repeated TypedKey keys = 1;
|
||||
// Hash of reassembled data to verify contents
|
||||
TypedKey hash = 2;
|
||||
@ -80,6 +81,7 @@ message DHTData {
|
||||
// Keys must use writable schema in order to make this list mutable
|
||||
message DHTList {
|
||||
// Other keys to concatenate
|
||||
// Uses the same writer as this DHTList with SMPL schema
|
||||
repeated TypedKey keys = 1;
|
||||
// Item position index
|
||||
// Actual item location is:
|
||||
@ -223,6 +225,16 @@ message Profile {
|
||||
optional TypedKey avatar = 5;
|
||||
}
|
||||
|
||||
// A pointer to an owned DHT record
|
||||
message OwnedDHTRecordPointer {
|
||||
// DHT Record key
|
||||
TypedKey record_key = 1;
|
||||
// DHT record owner key
|
||||
CryptoKey owner_key = 2;
|
||||
// DHT record owner secret
|
||||
CryptoKey owner_secret = 3;
|
||||
}
|
||||
|
||||
// A record of an individual account
|
||||
// Pointed to by the identity account map in the identity key
|
||||
//
|
||||
@ -236,6 +248,95 @@ message Account {
|
||||
// Auto-away sets 'away' mode after an inactivity time
|
||||
uint32 auto_away_timeout_sec = 3;
|
||||
// The contacts DHTList for this account
|
||||
// DHT Private: accountSecretKey
|
||||
TypedKey contact_list = 4;
|
||||
// DHT Private
|
||||
OwnedDHTRecordPointer contact_list = 4;
|
||||
// The contact requests DHTList for this account
|
||||
// DHT Private
|
||||
OwnedDHTRecordPointer contact_requests = 5;
|
||||
}
|
||||
|
||||
// EncryptionKind
|
||||
// Encryption of secret
|
||||
enum EncryptionKind {
|
||||
ENCRYPTION_KIND_UNSPECIFIED = 0;
|
||||
ENCRYPTION_KIND_PIN = 1;
|
||||
ENCRYPTION_KIND_PASSWORD =2;
|
||||
}
|
||||
|
||||
// Invitation that is shared for VeilidChat contact connections
|
||||
// serialized to QR code or data blob, not send over DHT, out of band.
|
||||
// Writer secret is unique to this invitation
|
||||
message ContactInvitation {
|
||||
// Contact request DHT record key
|
||||
TypedKey contact_request_record_key = 1;
|
||||
// Writer secret key bytes possibly encrypted
|
||||
bytes writer_secret = 2;
|
||||
}
|
||||
|
||||
// Signature of invitation with identity
|
||||
message SignedContactInvitation {
|
||||
// The serialized bytes for the contact invitation
|
||||
bytes contact_invitation = 1;
|
||||
// The signature of the contact_invitation bytes with the identity
|
||||
Signature identity_signature = 2;
|
||||
}
|
||||
|
||||
// Contact request unicastinbox on the DHT
|
||||
// DHTSchema: SMPL 2 owner key, 1 writer key symmetrically encrypted with writer secret
|
||||
message ContactRequest {
|
||||
// The salt for the encryption used on the unicastinbox writer secret
|
||||
bytes writer_salt = 1;
|
||||
// The kind of encryption used on the unicastinbox writer key
|
||||
EncryptionKind encryption_key_type = 2;
|
||||
// The private part encoded and symmetrically encrypted with the unicastinbox writer secret
|
||||
bytes private = 3;
|
||||
}
|
||||
|
||||
// The private part of a possibly encrypted contact request
|
||||
// Symmetrically encrypted with writer secret
|
||||
message ContactRequestPrivate {
|
||||
// Writer public key for signing writes to contact request unicastinbox
|
||||
CryptoKey writer_key = 1;
|
||||
// Snapshot of profile
|
||||
Profile profile = 2;
|
||||
// Account master dht key
|
||||
TypedKey account_master_record_key = 3;
|
||||
// Local chat DHT record key
|
||||
TypedKey chat_record_key = 4;
|
||||
// Expiration timestamp
|
||||
uint64 expiration = 5;
|
||||
}
|
||||
|
||||
// To accept or reject a contact request, fill this out and send to the ContactRequest unicastinbox
|
||||
message ContactResponse {
|
||||
// Accept or reject
|
||||
bool accept = 1;
|
||||
// Account master record key
|
||||
TypedKey account_master_record_key = 2;
|
||||
// Local chat DHT record key if accepted
|
||||
TypedKey chat_record_key = 3;
|
||||
}
|
||||
|
||||
// Signature of response with identity
|
||||
// Symmetrically encrypted with writer secret
|
||||
message SignedContactResponse {
|
||||
// Serialized bytes for ContactResponse
|
||||
bytes contact_response = 1;
|
||||
// Signature of the contact_accept bytes with the identity
|
||||
Signature identity_signature = 2;
|
||||
}
|
||||
|
||||
// Contact request record kept in Account DHTList to keep track of extant contact invitations
|
||||
message ContactRequestRecord {
|
||||
// Contact request unicastinbox DHT record key
|
||||
TypedKey contact_request_record_key = 1;
|
||||
// Unencrypted writer key for this request
|
||||
CryptoKey writer_key = 2;
|
||||
CryptoKey writer_secret = 3;
|
||||
// Local chat DHT record key
|
||||
TypedKey chat_record_key = 4;
|
||||
// Expiration timestamp
|
||||
uint64 expiration = 5;
|
||||
// A copy of the raw invitation bytes post-encryption
|
||||
bytes invitation = 6;
|
||||
}
|
48
lib/providers/contact_request_records.dart
Normal file
48
lib/providers/contact_request_records.dart
Normal file
@ -0,0 +1,48 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:veilid/veilid.dart';
|
||||
|
||||
import '../entities/entities.dart';
|
||||
import '../entities/proto.dart' as proto;
|
||||
import '../tools/tools.dart';
|
||||
import '../veilid_support/veilid_support.dart';
|
||||
import 'logins.dart';
|
||||
|
||||
part 'contact_request_records.g.dart';
|
||||
|
||||
// Contact invitation records stored in Account
|
||||
class ContactRequestRecords extends DHTList<proto.ContactRequestRecord> {
|
||||
//
|
||||
|
||||
Future<proto.ContactRequestRecord> newContactRequest(
|
||||
proto.EncryptionKind encryptionKind,
|
||||
String encryptionKey,
|
||||
) async {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
class ContactRequestRecordsParams {
|
||||
ContactRequestRecordsParams({required this.contactRequestsDHTListKey});
|
||||
TypedKey contactRequestsDHTListKey;
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Future<ContactRequestRecords?> fetchContactRequestRecords(
|
||||
FetchContactRequestRecordsRef ref,
|
||||
{required ContactRequestRecordsParams params}) async {
|
||||
// final localAccounts = await ref.watch(localAccountsProvider.future);
|
||||
// try {
|
||||
// return localAccounts.firstWhere(
|
||||
// (e) => e.identityMaster.masterRecordKey == accountMasterRecordKey);
|
||||
// } on Exception catch (e) {
|
||||
// if (e is StateError) {
|
||||
// return null;
|
||||
// }
|
||||
// rethrow;
|
||||
// }
|
||||
}
|
117
lib/providers/contact_request_records.g.dart
Normal file
117
lib/providers/contact_request_records.g.dart
Normal file
@ -0,0 +1,117 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'contact_request_records.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$fetchContactRequestRecordsHash() =>
|
||||
r'603c6d81b22d1cb4fd26cf32b98d3206ff6bc38c';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
_SystemHash._();
|
||||
|
||||
static int combine(int hash, int value) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + value);
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
|
||||
return hash ^ (hash >> 6);
|
||||
}
|
||||
|
||||
static int finish(int hash) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
|
||||
// ignore: parameter_assignments
|
||||
hash = hash ^ (hash >> 11);
|
||||
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
|
||||
}
|
||||
}
|
||||
|
||||
typedef FetchContactRequestRecordsRef
|
||||
= AutoDisposeFutureProviderRef<ContactRequestRecords?>;
|
||||
|
||||
/// See also [fetchContactRequestRecords].
|
||||
@ProviderFor(fetchContactRequestRecords)
|
||||
const fetchContactRequestRecordsProvider = FetchContactRequestRecordsFamily();
|
||||
|
||||
/// See also [fetchContactRequestRecords].
|
||||
class FetchContactRequestRecordsFamily
|
||||
extends Family<AsyncValue<ContactRequestRecords?>> {
|
||||
/// See also [fetchContactRequestRecords].
|
||||
const FetchContactRequestRecordsFamily();
|
||||
|
||||
/// See also [fetchContactRequestRecords].
|
||||
FetchContactRequestRecordsProvider call({
|
||||
required ContactRequestRecordsParams params,
|
||||
}) {
|
||||
return FetchContactRequestRecordsProvider(
|
||||
params: params,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
FetchContactRequestRecordsProvider getProviderOverride(
|
||||
covariant FetchContactRequestRecordsProvider provider,
|
||||
) {
|
||||
return call(
|
||||
params: provider.params,
|
||||
);
|
||||
}
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||
_allTransitiveDependencies;
|
||||
|
||||
@override
|
||||
String? get name => r'fetchContactRequestRecordsProvider';
|
||||
}
|
||||
|
||||
/// See also [fetchContactRequestRecords].
|
||||
class FetchContactRequestRecordsProvider
|
||||
extends AutoDisposeFutureProvider<ContactRequestRecords?> {
|
||||
/// See also [fetchContactRequestRecords].
|
||||
FetchContactRequestRecordsProvider({
|
||||
required this.params,
|
||||
}) : super.internal(
|
||||
(ref) => fetchContactRequestRecords(
|
||||
ref,
|
||||
params: params,
|
||||
),
|
||||
from: fetchContactRequestRecordsProvider,
|
||||
name: r'fetchContactRequestRecordsProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$fetchContactRequestRecordsHash,
|
||||
dependencies: FetchContactRequestRecordsFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
FetchContactRequestRecordsFamily._allTransitiveDependencies,
|
||||
);
|
||||
|
||||
final ContactRequestRecordsParams params;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is FetchContactRequestRecordsProvider &&
|
||||
other.params == params;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, params.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
|
43
lib/veilid_support/dht_list.dart
Normal file
43
lib/veilid_support/dht_list.dart
Normal file
@ -0,0 +1,43 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:protobuf/protobuf.dart';
|
||||
import 'package:veilid/veilid.dart';
|
||||
|
||||
import '../tools/tools.dart';
|
||||
import 'veilid_support.dart';
|
||||
|
||||
class DHTList {
|
||||
DHTList({required DHTRecord dhtRecord}) : _dhtRecord = dhtRecord;
|
||||
|
||||
final DHTRecord _dhtRecord;
|
||||
|
||||
static Future<DHTList> create(VeilidRoutingContext dhtctx,
|
||||
{DHTRecordCrypto? crypto}) async {
|
||||
final dhtRecord = await DHTRecord.create(dhtctx, crypto: crypto);
|
||||
final dhtList = DHTList(dhtRecord: dhtRecord);
|
||||
return dhtList;
|
||||
}
|
||||
|
||||
static Future<DHTList> openRead(
|
||||
VeilidRoutingContext dhtctx, TypedKey dhtRecordKey,
|
||||
{DHTRecordCrypto? crypto}) async {
|
||||
final dhtRecord =
|
||||
await DHTRecord.openRead(dhtctx, dhtRecordKey, crypto: crypto);
|
||||
final dhtList = DHTList(dhtRecord: dhtRecord);
|
||||
return dhtList;
|
||||
}
|
||||
|
||||
static Future<DHTList> openWrite(
|
||||
VeilidRoutingContext dhtctx,
|
||||
TypedKey dhtRecordKey,
|
||||
KeyPair writer, {
|
||||
DHTRecordCrypto? crypto,
|
||||
}) async {
|
||||
final dhtRecord =
|
||||
await DHTRecord.openWrite(dhtctx, dhtRecordKey, writer, crypto: crypto);
|
||||
final dhtList = DHTList(dhtRecord: dhtRecord);
|
||||
return dhtList;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
}
|
@ -3,6 +3,7 @@ import 'dart:typed_data';
|
||||
import 'package:protobuf/protobuf.dart';
|
||||
import 'package:veilid/veilid.dart';
|
||||
|
||||
import '../entities/proto.dart' as proto;
|
||||
import '../tools/tools.dart';
|
||||
import 'veilid_support.dart';
|
||||
|
||||
|
@ -7,6 +7,7 @@ import Foundation
|
||||
|
||||
import path_provider_foundation
|
||||
import screen_retriever
|
||||
import share_plus
|
||||
import shared_preferences_foundation
|
||||
import sqflite
|
||||
import url_launcher_macos
|
||||
@ -16,6 +17,7 @@ import window_manager
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
||||
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
|
24
pubspec.lock
24
pubspec.lock
@ -281,6 +281,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
cross_file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cross_file
|
||||
sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.3+4"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -981,6 +989,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
share_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: share_plus
|
||||
sha256: ed3fcea4f789ed95913328e629c0c53e69e80e08b6c24542f1b3576046c614e8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.2"
|
||||
share_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: share_plus_platform_interface
|
||||
sha256: "0c6e61471bd71b04a138b8b588fa388e66d8b005e6f2deda63371c5c505a0981"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -47,6 +47,7 @@ dependencies:
|
||||
radix_colors: ^1.0.4
|
||||
reorderable_grid: ^1.0.7
|
||||
riverpod_annotation: ^2.1.1
|
||||
share_plus: ^7.0.2
|
||||
shared_preferences: ^2.0.15
|
||||
signal_strength_indicator: ^0.4.1
|
||||
split_view: ^3.2.1
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <screen_retriever/screen_retriever_plugin.h>
|
||||
#include <share_plus/share_plus_windows_plugin_c_api.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
#include <veilid/veilid_plugin.h>
|
||||
#include <window_manager/window_manager_plugin.h>
|
||||
@ -14,6 +15,8 @@
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
ScreenRetrieverPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
|
||||
SharePlusWindowsPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||
VeilidPluginRegisterWithRegistrar(
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
screen_retriever
|
||||
share_plus
|
||||
url_launcher_windows
|
||||
veilid
|
||||
window_manager
|
||||
|
Loading…
Reference in New Issue
Block a user