clean code

This commit is contained in:
otsmr 2025-05-30 21:43:55 +02:00
parent 2c22067a54
commit e69870ea14
17 changed files with 609 additions and 114 deletions

View file

@ -0,0 +1,4 @@
class SecureStorageKeys {
static const String signalIdentity = "signal_identity";
static const String signalSignedPreKey = "signed_pre_key_store";
}

View file

@ -3,13 +3,14 @@ import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
import 'package:twonly/src/constants/secure_storage_keys.dart';
class ConnectSignedPreKeyStore extends SignedPreKeyStore { class ConnectSignedPreKeyStore extends SignedPreKeyStore {
// final store = HashMap<int, Uint8List>();
Future<HashMap<int, Uint8List>> getStore() async { Future<HashMap<int, Uint8List>> getStore() async {
final storage = FlutterSecureStorage(); final storage = FlutterSecureStorage();
final storeSerialized = await storage.read(key: "signed_pre_key_store"); final storeSerialized = await storage.read(
key: SecureStorageKeys.signalSignedPreKey,
);
var store = HashMap<int, Uint8List>(); var store = HashMap<int, Uint8List>();
if (storeSerialized == null) { if (storeSerialized == null) {
return store; return store;
@ -21,6 +22,24 @@ class ConnectSignedPreKeyStore extends SignedPreKeyStore {
return store; return store;
} }
Future<int> getNextKeyId() async {
final storage = FlutterSecureStorage();
final storeSerialized = await storage.read(
key: SecureStorageKeys.signalSignedPreKey,
);
if (storeSerialized == null) {
return 0;
}
final storeHashMap = json.decode(storeSerialized);
var maxKeyId = 0;
for (final item in storeHashMap) {
if (maxKeyId < item[0]) {
maxKeyId = item[0];
}
}
return maxKeyId + 1;
}
Future safeStore(HashMap<int, Uint8List> store) async { Future safeStore(HashMap<int, Uint8List> store) async {
final storage = FlutterSecureStorage(); final storage = FlutterSecureStorage();
var storeHashMap = []; var storeHashMap = [];
@ -28,7 +47,10 @@ class ConnectSignedPreKeyStore extends SignedPreKeyStore {
storeHashMap.add([item.key, base64Encode(item.value)]); storeHashMap.add([item.key, base64Encode(item.value)]);
} }
final storeSerialized = json.encode(storeHashMap); final storeSerialized = json.encode(storeHashMap);
await storage.write(key: "signed_pre_key_store", value: storeSerialized); await storage.write(
key: SecureStorageKeys.signalSignedPreKey,
value: storeSerialized,
);
} }
@override @override
@ -36,7 +58,8 @@ class ConnectSignedPreKeyStore extends SignedPreKeyStore {
final store = await getStore(); final store = await getStore();
if (!store.containsKey(signedPreKeyId)) { if (!store.containsKey(signedPreKeyId)) {
throw InvalidKeyIdException( throw InvalidKeyIdException(
'No such signedprekeyrecord! $signedPreKeyId'); 'No such signed prekey record! $signedPreKeyId',
);
} }
return SignedPreKeyRecord.fromSerialized(store[signedPreKeyId]!); return SignedPreKeyRecord.fromSerialized(store[signedPreKeyId]!);
} }
@ -53,7 +76,9 @@ class ConnectSignedPreKeyStore extends SignedPreKeyStore {
@override @override
Future<void> storeSignedPreKey( Future<void> storeSignedPreKey(
int signedPreKeyId, SignedPreKeyRecord record) async { int signedPreKeyId,
SignedPreKeyRecord record,
) async {
final store = await getStore(); final store = await getStore();
store[signedPreKeyId] = record.serialize(); store[signedPreKeyId] = record.serialize();
await safeStore(store); await safeStore(store);

View file

@ -36,6 +36,8 @@ class UserData {
int? myBestFriendContactId; int? myBestFriendContactId;
DateTime? signalLastSignedPreKeyUpdated;
final int userId; final int userId;
factory UserData.fromJson(Map<String, dynamic> json) => factory UserData.fromJson(Map<String, dynamic> json) =>

View file

@ -36,8 +36,11 @@ UserData _$UserDataFromJson(Map<String, dynamic> json) => UserData(
? null ? null
: DateTime.parse(json['lastImageSend'] as String) : DateTime.parse(json['lastImageSend'] as String)
..todaysImageCounter = (json['todaysImageCounter'] as num?)?.toInt() ..todaysImageCounter = (json['todaysImageCounter'] as num?)?.toInt()
..myBestFriendContactId = ..myBestFriendContactId = (json['myBestFriendContactId'] as num?)?.toInt()
(json['myBestFriendContactId'] as num?)?.toInt(); ..signalLastSignedPreKeyUpdated =
json['signalLastSignedPreKeyUpdated'] == null
? null
: DateTime.parse(json['signalLastSignedPreKeyUpdated'] as String);
Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{ Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
'username': instance.username, 'username': instance.username,
@ -58,6 +61,8 @@ Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
'lastImageSend': instance.lastImageSend?.toIso8601String(), 'lastImageSend': instance.lastImageSend?.toIso8601String(),
'todaysImageCounter': instance.todaysImageCounter, 'todaysImageCounter': instance.todaysImageCounter,
'myBestFriendContactId': instance.myBestFriendContactId, 'myBestFriendContactId': instance.myBestFriendContactId,
'signalLastSignedPreKeyUpdated':
instance.signalLastSignedPreKeyUpdated?.toIso8601String(),
'userId': instance.userId, 'userId': instance.userId,
}; };

View file

@ -1403,6 +1403,134 @@ class ApplicationData_GetPrekeysByUserId extends $pb.GeneratedMessage {
void clearUserId() => clearField(1); void clearUserId() => clearField(1);
} }
class ApplicationData_GetSignedPreKeyByUserId extends $pb.GeneratedMessage {
factory ApplicationData_GetSignedPreKeyByUserId({
$fixnum.Int64? userId,
}) {
final $result = create();
if (userId != null) {
$result.userId = userId;
}
return $result;
}
ApplicationData_GetSignedPreKeyByUserId._() : super();
factory ApplicationData_GetSignedPreKeyByUserId.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory ApplicationData_GetSignedPreKeyByUserId.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ApplicationData.GetSignedPreKeyByUserId', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..aInt64(1, _omitFieldNames ? '' : 'userId')
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
ApplicationData_GetSignedPreKeyByUserId clone() => ApplicationData_GetSignedPreKeyByUserId()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
ApplicationData_GetSignedPreKeyByUserId copyWith(void Function(ApplicationData_GetSignedPreKeyByUserId) updates) => super.copyWith((message) => updates(message as ApplicationData_GetSignedPreKeyByUserId)) as ApplicationData_GetSignedPreKeyByUserId;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static ApplicationData_GetSignedPreKeyByUserId create() => ApplicationData_GetSignedPreKeyByUserId._();
ApplicationData_GetSignedPreKeyByUserId createEmptyInstance() => create();
static $pb.PbList<ApplicationData_GetSignedPreKeyByUserId> createRepeated() => $pb.PbList<ApplicationData_GetSignedPreKeyByUserId>();
@$core.pragma('dart2js:noInline')
static ApplicationData_GetSignedPreKeyByUserId getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ApplicationData_GetSignedPreKeyByUserId>(create);
static ApplicationData_GetSignedPreKeyByUserId? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get userId => $_getI64(0);
@$pb.TagNumber(1)
set userId($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasUserId() => $_has(0);
@$pb.TagNumber(1)
void clearUserId() => clearField(1);
}
class ApplicationData_UpdateSignedPreKey extends $pb.GeneratedMessage {
factory ApplicationData_UpdateSignedPreKey({
$fixnum.Int64? signedPrekeyId,
$core.List<$core.int>? signedPrekey,
$core.List<$core.int>? signedPrekeySignature,
}) {
final $result = create();
if (signedPrekeyId != null) {
$result.signedPrekeyId = signedPrekeyId;
}
if (signedPrekey != null) {
$result.signedPrekey = signedPrekey;
}
if (signedPrekeySignature != null) {
$result.signedPrekeySignature = signedPrekeySignature;
}
return $result;
}
ApplicationData_UpdateSignedPreKey._() : super();
factory ApplicationData_UpdateSignedPreKey.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory ApplicationData_UpdateSignedPreKey.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ApplicationData.UpdateSignedPreKey', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..aInt64(1, _omitFieldNames ? '' : 'signedPrekeyId')
..a<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'signedPrekey', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(3, _omitFieldNames ? '' : 'signedPrekeySignature', $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')
ApplicationData_UpdateSignedPreKey clone() => ApplicationData_UpdateSignedPreKey()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
ApplicationData_UpdateSignedPreKey copyWith(void Function(ApplicationData_UpdateSignedPreKey) updates) => super.copyWith((message) => updates(message as ApplicationData_UpdateSignedPreKey)) as ApplicationData_UpdateSignedPreKey;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static ApplicationData_UpdateSignedPreKey create() => ApplicationData_UpdateSignedPreKey._();
ApplicationData_UpdateSignedPreKey createEmptyInstance() => create();
static $pb.PbList<ApplicationData_UpdateSignedPreKey> createRepeated() => $pb.PbList<ApplicationData_UpdateSignedPreKey>();
@$core.pragma('dart2js:noInline')
static ApplicationData_UpdateSignedPreKey getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ApplicationData_UpdateSignedPreKey>(create);
static ApplicationData_UpdateSignedPreKey? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get signedPrekeyId => $_getI64(0);
@$pb.TagNumber(1)
set signedPrekeyId($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasSignedPrekeyId() => $_has(0);
@$pb.TagNumber(1)
void clearSignedPrekeyId() => clearField(1);
@$pb.TagNumber(2)
$core.List<$core.int> get signedPrekey => $_getN(1);
@$pb.TagNumber(2)
set signedPrekey($core.List<$core.int> v) { $_setBytes(1, v); }
@$pb.TagNumber(2)
$core.bool hasSignedPrekey() => $_has(1);
@$pb.TagNumber(2)
void clearSignedPrekey() => clearField(2);
@$pb.TagNumber(3)
$core.List<$core.int> get signedPrekeySignature => $_getN(2);
@$pb.TagNumber(3)
set signedPrekeySignature($core.List<$core.int> v) { $_setBytes(2, v); }
@$pb.TagNumber(3)
$core.bool hasSignedPrekeySignature() => $_has(2);
@$pb.TagNumber(3)
void clearSignedPrekeySignature() => clearField(3);
}
class ApplicationData_GetUploadToken extends $pb.GeneratedMessage { class ApplicationData_GetUploadToken extends $pb.GeneratedMessage {
factory ApplicationData_GetUploadToken({ factory ApplicationData_GetUploadToken({
$core.int? recipientsCount, $core.int? recipientsCount,
@ -1745,6 +1873,8 @@ enum ApplicationData_ApplicationData {
updateplanoptions, updateplanoptions,
downloaddone, downloaddone,
uploaddone, uploaddone,
getsignedprekeybyuserid,
updatesignedprekey,
notSet notSet
} }
@ -1771,6 +1901,8 @@ class ApplicationData extends $pb.GeneratedMessage {
ApplicationData_UpdatePlanOptions? updateplanoptions, ApplicationData_UpdatePlanOptions? updateplanoptions,
ApplicationData_DownloadDone? downloaddone, ApplicationData_DownloadDone? downloaddone,
ApplicationData_UploadDone? uploaddone, ApplicationData_UploadDone? uploaddone,
ApplicationData_GetSignedPreKeyByUserId? getsignedprekeybyuserid,
ApplicationData_UpdateSignedPreKey? updatesignedprekey,
}) { }) {
final $result = create(); final $result = create();
if (textmessage != null) { if (textmessage != null) {
@ -1836,6 +1968,12 @@ class ApplicationData extends $pb.GeneratedMessage {
if (uploaddone != null) { if (uploaddone != null) {
$result.uploaddone = uploaddone; $result.uploaddone = uploaddone;
} }
if (getsignedprekeybyuserid != null) {
$result.getsignedprekeybyuserid = getsignedprekeybyuserid;
}
if (updatesignedprekey != null) {
$result.updatesignedprekey = updatesignedprekey;
}
return $result; return $result;
} }
ApplicationData._() : super(); ApplicationData._() : super();
@ -1864,10 +2002,12 @@ class ApplicationData extends $pb.GeneratedMessage {
19 : ApplicationData_ApplicationData.updateplanoptions, 19 : ApplicationData_ApplicationData.updateplanoptions,
20 : ApplicationData_ApplicationData.downloaddone, 20 : ApplicationData_ApplicationData.downloaddone,
21 : ApplicationData_ApplicationData.uploaddone, 21 : ApplicationData_ApplicationData.uploaddone,
22 : ApplicationData_ApplicationData.getsignedprekeybyuserid,
23 : ApplicationData_ApplicationData.updatesignedprekey,
0 : ApplicationData_ApplicationData.notSet 0 : ApplicationData_ApplicationData.notSet
}; };
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ApplicationData', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create) static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ApplicationData', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..oo(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]) ..oo(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23])
..aOM<ApplicationData_TextMessage>(1, _omitFieldNames ? '' : 'textmessage', subBuilder: ApplicationData_TextMessage.create) ..aOM<ApplicationData_TextMessage>(1, _omitFieldNames ? '' : 'textmessage', subBuilder: ApplicationData_TextMessage.create)
..aOM<ApplicationData_GetUserByUsername>(2, _omitFieldNames ? '' : 'getuserbyusername', subBuilder: ApplicationData_GetUserByUsername.create) ..aOM<ApplicationData_GetUserByUsername>(2, _omitFieldNames ? '' : 'getuserbyusername', subBuilder: ApplicationData_GetUserByUsername.create)
..aOM<ApplicationData_GetPrekeysByUserId>(3, _omitFieldNames ? '' : 'getprekeysbyuserid', subBuilder: ApplicationData_GetPrekeysByUserId.create) ..aOM<ApplicationData_GetPrekeysByUserId>(3, _omitFieldNames ? '' : 'getprekeysbyuserid', subBuilder: ApplicationData_GetPrekeysByUserId.create)
@ -1889,6 +2029,8 @@ class ApplicationData extends $pb.GeneratedMessage {
..aOM<ApplicationData_UpdatePlanOptions>(19, _omitFieldNames ? '' : 'updateplanoptions', subBuilder: ApplicationData_UpdatePlanOptions.create) ..aOM<ApplicationData_UpdatePlanOptions>(19, _omitFieldNames ? '' : 'updateplanoptions', subBuilder: ApplicationData_UpdatePlanOptions.create)
..aOM<ApplicationData_DownloadDone>(20, _omitFieldNames ? '' : 'downloaddone', subBuilder: ApplicationData_DownloadDone.create) ..aOM<ApplicationData_DownloadDone>(20, _omitFieldNames ? '' : 'downloaddone', subBuilder: ApplicationData_DownloadDone.create)
..aOM<ApplicationData_UploadDone>(21, _omitFieldNames ? '' : 'uploaddone', subBuilder: ApplicationData_UploadDone.create) ..aOM<ApplicationData_UploadDone>(21, _omitFieldNames ? '' : 'uploaddone', subBuilder: ApplicationData_UploadDone.create)
..aOM<ApplicationData_GetSignedPreKeyByUserId>(22, _omitFieldNames ? '' : 'getsignedprekeybyuserid', subBuilder: ApplicationData_GetSignedPreKeyByUserId.create)
..aOM<ApplicationData_UpdateSignedPreKey>(23, _omitFieldNames ? '' : 'updatesignedprekey', subBuilder: ApplicationData_UpdateSignedPreKey.create)
..hasRequiredFields = false ..hasRequiredFields = false
; ;
@ -2146,6 +2288,28 @@ class ApplicationData extends $pb.GeneratedMessage {
void clearUploaddone() => clearField(21); void clearUploaddone() => clearField(21);
@$pb.TagNumber(21) @$pb.TagNumber(21)
ApplicationData_UploadDone ensureUploaddone() => $_ensure(20); ApplicationData_UploadDone ensureUploaddone() => $_ensure(20);
@$pb.TagNumber(22)
ApplicationData_GetSignedPreKeyByUserId get getsignedprekeybyuserid => $_getN(21);
@$pb.TagNumber(22)
set getsignedprekeybyuserid(ApplicationData_GetSignedPreKeyByUserId v) { setField(22, v); }
@$pb.TagNumber(22)
$core.bool hasGetsignedprekeybyuserid() => $_has(21);
@$pb.TagNumber(22)
void clearGetsignedprekeybyuserid() => clearField(22);
@$pb.TagNumber(22)
ApplicationData_GetSignedPreKeyByUserId ensureGetsignedprekeybyuserid() => $_ensure(21);
@$pb.TagNumber(23)
ApplicationData_UpdateSignedPreKey get updatesignedprekey => $_getN(22);
@$pb.TagNumber(23)
set updatesignedprekey(ApplicationData_UpdateSignedPreKey v) { setField(23, v); }
@$pb.TagNumber(23)
$core.bool hasUpdatesignedprekey() => $_has(22);
@$pb.TagNumber(23)
void clearUpdatesignedprekey() => clearField(23);
@$pb.TagNumber(23)
ApplicationData_UpdateSignedPreKey ensureUpdatesignedprekey() => $_ensure(22);
} }
class Response_PreKey extends $pb.GeneratedMessage { class Response_PreKey extends $pb.GeneratedMessage {

View file

@ -157,8 +157,10 @@ const ApplicationData$json = {
{'1': 'updateplanoptions', '3': 19, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.UpdatePlanOptions', '9': 0, '10': 'updateplanoptions'}, {'1': 'updateplanoptions', '3': 19, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.UpdatePlanOptions', '9': 0, '10': 'updateplanoptions'},
{'1': 'downloaddone', '3': 20, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.DownloadDone', '9': 0, '10': 'downloaddone'}, {'1': 'downloaddone', '3': 20, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.DownloadDone', '9': 0, '10': 'downloaddone'},
{'1': 'uploaddone', '3': 21, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.UploadDone', '9': 0, '10': 'uploaddone'}, {'1': 'uploaddone', '3': 21, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.UploadDone', '9': 0, '10': 'uploaddone'},
{'1': 'getsignedprekeybyuserid', '3': 22, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.GetSignedPreKeyByUserId', '9': 0, '10': 'getsignedprekeybyuserid'},
{'1': 'updatesignedprekey', '3': 23, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.UpdateSignedPreKey', '9': 0, '10': 'updatesignedprekey'},
], ],
'3': [ApplicationData_TextMessage$json, ApplicationData_GetUserByUsername$json, ApplicationData_UpdateGoogleFcmToken$json, ApplicationData_GetUserById$json, ApplicationData_RedeemVoucher$json, ApplicationData_SwitchToPayedPlan$json, ApplicationData_UpdatePlanOptions$json, ApplicationData_CreateVoucher$json, ApplicationData_GetLocation$json, ApplicationData_GetVouchers$json, ApplicationData_GetAvailablePlans$json, ApplicationData_GetAddAccountsInvites$json, ApplicationData_GetCurrentPlanInfos$json, ApplicationData_RedeemAdditionalCode$json, ApplicationData_RemoveAdditionalUser$json, ApplicationData_GetPrekeysByUserId$json, ApplicationData_GetUploadToken$json, ApplicationData_UploadData$json, ApplicationData_UploadDone$json, ApplicationData_DownloadData$json, ApplicationData_DownloadDone$json], '3': [ApplicationData_TextMessage$json, ApplicationData_GetUserByUsername$json, ApplicationData_UpdateGoogleFcmToken$json, ApplicationData_GetUserById$json, ApplicationData_RedeemVoucher$json, ApplicationData_SwitchToPayedPlan$json, ApplicationData_UpdatePlanOptions$json, ApplicationData_CreateVoucher$json, ApplicationData_GetLocation$json, ApplicationData_GetVouchers$json, ApplicationData_GetAvailablePlans$json, ApplicationData_GetAddAccountsInvites$json, ApplicationData_GetCurrentPlanInfos$json, ApplicationData_RedeemAdditionalCode$json, ApplicationData_RemoveAdditionalUser$json, ApplicationData_GetPrekeysByUserId$json, ApplicationData_GetSignedPreKeyByUserId$json, ApplicationData_UpdateSignedPreKey$json, ApplicationData_GetUploadToken$json, ApplicationData_UploadData$json, ApplicationData_UploadDone$json, ApplicationData_DownloadData$json, ApplicationData_DownloadDone$json],
'8': [ '8': [
{'1': 'ApplicationData'}, {'1': 'ApplicationData'},
], ],
@ -284,6 +286,24 @@ const ApplicationData_GetPrekeysByUserId$json = {
], ],
}; };
@$core.Deprecated('Use applicationDataDescriptor instead')
const ApplicationData_GetSignedPreKeyByUserId$json = {
'1': 'GetSignedPreKeyByUserId',
'2': [
{'1': 'user_id', '3': 1, '4': 1, '5': 3, '10': 'userId'},
],
};
@$core.Deprecated('Use applicationDataDescriptor instead')
const ApplicationData_UpdateSignedPreKey$json = {
'1': 'UpdateSignedPreKey',
'2': [
{'1': 'signed_prekey_id', '3': 1, '4': 1, '5': 3, '10': 'signedPrekeyId'},
{'1': 'signed_prekey', '3': 2, '4': 1, '5': 12, '10': 'signedPrekey'},
{'1': 'signed_prekey_signature', '3': 3, '4': 1, '5': 12, '10': 'signedPrekeySignature'},
],
};
@$core.Deprecated('Use applicationDataDescriptor instead') @$core.Deprecated('Use applicationDataDescriptor instead')
const ApplicationData_GetUploadToken$json = { const ApplicationData_GetUploadToken$json = {
'1': 'GetUploadToken', '1': 'GetUploadToken',
@ -370,29 +390,36 @@ final $typed_data.Uint8List applicationDataDescriptor = $convert.base64Decode(
'VwbGFub3B0aW9ucxJUCgxkb3dubG9hZGRvbmUYFCABKAsyLi5jbGllbnRfdG9fc2VydmVyLkFw' 'VwbGFub3B0aW9ucxJUCgxkb3dubG9hZGRvbmUYFCABKAsyLi5jbGllbnRfdG9fc2VydmVyLkFw'
'cGxpY2F0aW9uRGF0YS5Eb3dubG9hZERvbmVIAFIMZG93bmxvYWRkb25lEk4KCnVwbG9hZGRvbm' 'cGxpY2F0aW9uRGF0YS5Eb3dubG9hZERvbmVIAFIMZG93bmxvYWRkb25lEk4KCnVwbG9hZGRvbm'
'UYFSABKAsyLC5jbGllbnRfdG9fc2VydmVyLkFwcGxpY2F0aW9uRGF0YS5VcGxvYWREb25lSABS' 'UYFSABKAsyLC5jbGllbnRfdG9fc2VydmVyLkFwcGxpY2F0aW9uRGF0YS5VcGxvYWREb25lSABS'
'CnVwbG9hZGRvbmUaagoLVGV4dE1lc3NhZ2USFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkEhIKBG' 'CnVwbG9hZGRvbmUSdQoXZ2V0c2lnbmVkcHJla2V5Ynl1c2VyaWQYFiABKAsyOS5jbGllbnRfdG'
'JvZHkYAyABKAxSBGJvZHkSIAoJcHVzaF9kYXRhGAQgASgMSABSCHB1c2hEYXRhiAEBQgwKCl9w' '9fc2VydmVyLkFwcGxpY2F0aW9uRGF0YS5HZXRTaWduZWRQcmVLZXlCeVVzZXJJZEgAUhdnZXRz'
'dXNoX2RhdGEaLwoRR2V0VXNlckJ5VXNlcm5hbWUSGgoIdXNlcm5hbWUYASABKAlSCHVzZXJuYW' 'aWduZWRwcmVrZXlieXVzZXJpZBJmChJ1cGRhdGVzaWduZWRwcmVrZXkYFyABKAsyNC5jbGllbn'
'1lGjUKFFVwZGF0ZUdvb2dsZUZjbVRva2VuEh0KCmdvb2dsZV9mY20YASABKAlSCWdvb2dsZUZj' 'RfdG9fc2VydmVyLkFwcGxpY2F0aW9uRGF0YS5VcGRhdGVTaWduZWRQcmVLZXlIAFISdXBkYXRl'
'bRomCgtHZXRVc2VyQnlJZBIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQaKQoNUmVkZWVtVm91Y2' 'c2lnbmVkcHJla2V5GmoKC1RleHRNZXNzYWdlEhcKB3VzZXJfaWQYASABKANSBnVzZXJJZBISCg'
'hlchIYCgd2b3VjaGVyGAEgASgJUgd2b3VjaGVyGnAKEVN3aXRjaFRvUGF5ZWRQbGFuEhcKB3Bs' 'Rib2R5GAMgASgMUgRib2R5EiAKCXB1c2hfZGF0YRgEIAEoDEgAUghwdXNoRGF0YYgBAUIMCgpf'
'YW5faWQYASABKAlSBnBsYW5JZBIfCgtwYXlfbW9udGhseRgCIAEoCFIKcGF5TW9udGhseRIhCg' 'cHVzaF9kYXRhGi8KEUdldFVzZXJCeVVzZXJuYW1lEhoKCHVzZXJuYW1lGAEgASgJUgh1c2Vybm'
'xhdXRvX3JlbmV3YWwYAyABKAhSC2F1dG9SZW5ld2FsGjYKEVVwZGF0ZVBsYW5PcHRpb25zEiEK' 'FtZRo1ChRVcGRhdGVHb29nbGVGY21Ub2tlbhIdCgpnb29nbGVfZmNtGAEgASgJUglnb29nbGVG'
'DGF1dG9fcmVuZXdhbBgBIAEoCFILYXV0b1JlbmV3YWwaMAoNQ3JlYXRlVm91Y2hlchIfCgt2YW' 'Y20aJgoLR2V0VXNlckJ5SWQSFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkGikKDVJlZGVlbVZvdW'
'x1ZV9jZW50cxgBIAEoDVIKdmFsdWVDZW50cxoNCgtHZXRMb2NhdGlvbhoNCgtHZXRWb3VjaGVy' 'NoZXISGAoHdm91Y2hlchgBIAEoCVIHdm91Y2hlchpwChFTd2l0Y2hUb1BheWVkUGxhbhIXCgdw'
'cxoTChFHZXRBdmFpbGFibGVQbGFucxoXChVHZXRBZGRBY2NvdW50c0ludml0ZXMaFQoTR2V0Q3' 'bGFuX2lkGAEgASgJUgZwbGFuSWQSHwoLcGF5X21vbnRobHkYAiABKAhSCnBheU1vbnRobHkSIQ'
'VycmVudFBsYW5JbmZvcxo3ChRSZWRlZW1BZGRpdGlvbmFsQ29kZRIfCgtpbnZpdGVfY29kZRgC' 'oMYXV0b19yZW5ld2FsGAMgASgIUgthdXRvUmVuZXdhbBo2ChFVcGRhdGVQbGFuT3B0aW9ucxIh'
'IAEoCVIKaW52aXRlQ29kZRovChRSZW1vdmVBZGRpdGlvbmFsVXNlchIXCgd1c2VyX2lkGAEgAS' 'CgxhdXRvX3JlbmV3YWwYASABKAhSC2F1dG9SZW5ld2FsGjAKDUNyZWF0ZVZvdWNoZXISHwoLdm'
'gDUgZ1c2VySWQaLQoSR2V0UHJla2V5c0J5VXNlcklkEhcKB3VzZXJfaWQYASABKANSBnVzZXJJ' 'FsdWVfY2VudHMYASABKA1SCnZhbHVlQ2VudHMaDQoLR2V0TG9jYXRpb24aDQoLR2V0Vm91Y2hl'
'ZBo7Cg5HZXRVcGxvYWRUb2tlbhIpChByZWNpcGllbnRzX2NvdW50GAEgASgNUg9yZWNpcGllbn' 'cnMaEwoRR2V0QXZhaWxhYmxlUGxhbnMaFwoVR2V0QWRkQWNjb3VudHNJbnZpdGVzGhUKE0dldE'
'RzQ291bnQaiQEKClVwbG9hZERhdGESIQoMdXBsb2FkX3Rva2VuGAEgASgMUgt1cGxvYWRUb2tl' 'N1cnJlbnRQbGFuSW5mb3MaNwoUUmVkZWVtQWRkaXRpb25hbENvZGUSHwoLaW52aXRlX2NvZGUY'
'bhIWCgZvZmZzZXQYAiABKA1SBm9mZnNldBISCgRkYXRhGAMgASgMUgRkYXRhEh8KCGNoZWNrc3' 'AiABKAlSCmludml0ZUNvZGUaLwoUUmVtb3ZlQWRkaXRpb25hbFVzZXISFwoHdXNlcl9pZBgBIA'
'VtGAQgASgMSABSCGNoZWNrc3VtiAEBQgsKCV9jaGVja3N1bRpaCgpVcGxvYWREb25lEiEKDHVw' 'EoA1IGdXNlcklkGi0KEkdldFByZWtleXNCeVVzZXJJZBIXCgd1c2VyX2lkGAEgASgDUgZ1c2Vy'
'bG9hZF90b2tlbhgBIAEoDFILdXBsb2FkVG9rZW4SKQoQcmVjaXBpZW50c19jb3VudBgCIAEoDV' 'SWQaMgoXR2V0U2lnbmVkUHJlS2V5QnlVc2VySWQSFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkGp'
'IPcmVjaXBpZW50c0NvdW50Gk0KDERvd25sb2FkRGF0YRIlCg5kb3dubG9hZF90b2tlbhgBIAEo' 'sBChJVcGRhdGVTaWduZWRQcmVLZXkSKAoQc2lnbmVkX3ByZWtleV9pZBgBIAEoA1IOc2lnbmVk'
'DFINZG93bmxvYWRUb2tlbhIWCgZvZmZzZXQYAiABKA1SBm9mZnNldBo1CgxEb3dubG9hZERvbm' 'UHJla2V5SWQSIwoNc2lnbmVkX3ByZWtleRgCIAEoDFIMc2lnbmVkUHJla2V5EjYKF3NpZ25lZF'
'USJQoOZG93bmxvYWRfdG9rZW4YASABKAxSDWRvd25sb2FkVG9rZW5CEQoPQXBwbGljYXRpb25E' '9wcmVrZXlfc2lnbmF0dXJlGAMgASgMUhVzaWduZWRQcmVrZXlTaWduYXR1cmUaOwoOR2V0VXBs'
'YXRh'); 'b2FkVG9rZW4SKQoQcmVjaXBpZW50c19jb3VudBgBIAEoDVIPcmVjaXBpZW50c0NvdW50GokBCg'
'pVcGxvYWREYXRhEiEKDHVwbG9hZF90b2tlbhgBIAEoDFILdXBsb2FkVG9rZW4SFgoGb2Zmc2V0'
'GAIgASgNUgZvZmZzZXQSEgoEZGF0YRgDIAEoDFIEZGF0YRIfCghjaGVja3N1bRgEIAEoDEgAUg'
'hjaGVja3N1bYgBAUILCglfY2hlY2tzdW0aWgoKVXBsb2FkRG9uZRIhCgx1cGxvYWRfdG9rZW4Y'
'ASABKAxSC3VwbG9hZFRva2VuEikKEHJlY2lwaWVudHNfY291bnQYAiABKA1SD3JlY2lwaWVudH'
'NDb3VudBpNCgxEb3dubG9hZERhdGESJQoOZG93bmxvYWRfdG9rZW4YASABKAxSDWRvd25sb2Fk'
'VG9rZW4SFgoGb2Zmc2V0GAIgASgNUgZvZmZzZXQaNQoMRG93bmxvYWREb25lEiUKDmRvd25sb2'
'FkX3Rva2VuGAEgASgMUg1kb3dubG9hZFRva2VuQhEKD0FwcGxpY2F0aW9uRGF0YQ==');
@$core.Deprecated('Use responseDescriptor instead') @$core.Deprecated('Use responseDescriptor instead')
const Response$json = { const Response$json = {

View file

@ -43,6 +43,7 @@ class ErrorCode extends $pb.ProtobufEnum {
static const ErrorCode NotEnoughCredit = ErrorCode._(1024, _omitEnumNames ? '' : 'NotEnoughCredit'); static const ErrorCode NotEnoughCredit = ErrorCode._(1024, _omitEnumNames ? '' : 'NotEnoughCredit');
static const ErrorCode PlanDowngrade = ErrorCode._(1025, _omitEnumNames ? '' : 'PlanDowngrade'); static const ErrorCode PlanDowngrade = ErrorCode._(1025, _omitEnumNames ? '' : 'PlanDowngrade');
static const ErrorCode PlanUpgradeNotYearly = ErrorCode._(1026, _omitEnumNames ? '' : 'PlanUpgradeNotYearly'); static const ErrorCode PlanUpgradeNotYearly = ErrorCode._(1026, _omitEnumNames ? '' : 'PlanUpgradeNotYearly');
static const ErrorCode InvalidSignedPreKey = ErrorCode._(1027, _omitEnumNames ? '' : 'InvalidSignedPreKey');
static const $core.List<ErrorCode> values = <ErrorCode> [ static const $core.List<ErrorCode> values = <ErrorCode> [
Unknown, Unknown,
@ -74,6 +75,7 @@ class ErrorCode extends $pb.ProtobufEnum {
NotEnoughCredit, NotEnoughCredit,
PlanDowngrade, PlanDowngrade,
PlanUpgradeNotYearly, PlanUpgradeNotYearly,
InvalidSignedPreKey,
]; ];
static final $core.Map<$core.int, ErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values); static final $core.Map<$core.int, ErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);

View file

@ -46,6 +46,7 @@ const ErrorCode$json = {
{'1': 'NotEnoughCredit', '2': 1024}, {'1': 'NotEnoughCredit', '2': 1024},
{'1': 'PlanDowngrade', '2': 1025}, {'1': 'PlanDowngrade', '2': 1025},
{'1': 'PlanUpgradeNotYearly', '2': 1026}, {'1': 'PlanUpgradeNotYearly', '2': 1026},
{'1': 'InvalidSignedPreKey', '2': 1027},
], ],
}; };
@ -63,5 +64,6 @@ final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode(
'4Q+QcSGAoTQXBpRW5kcG9pbnROb3RGb3VuZBD6BxIWChFBdXRoVG9rZW5Ob3RWYWxpZBD7BxIT' '4Q+QcSGAoTQXBpRW5kcG9pbnROb3RGb3VuZBD6BxIWChFBdXRoVG9rZW5Ob3RWYWxpZBD7BxIT'
'Cg5JbnZhbGlkUHJlS2V5cxD8BxITCg5Wb3VjaGVySW5WYWxpZBD9BxITCg5QbGFuTm90QWxsb3' 'Cg5JbnZhbGlkUHJlS2V5cxD8BxITCg5Wb3VjaGVySW5WYWxpZBD9BxITCg5QbGFuTm90QWxsb3'
'dlZBD+BxIVChBQbGFuTGltaXRSZWFjaGVkEP8HEhQKD05vdEVub3VnaENyZWRpdBCACBISCg1Q' 'dlZBD+BxIVChBQbGFuTGltaXRSZWFjaGVkEP8HEhQKD05vdEVub3VnaENyZWRpdBCACBISCg1Q'
'bGFuRG93bmdyYWRlEIEIEhkKFFBsYW5VcGdyYWRlTm90WWVhcmx5EIII'); 'bGFuRG93bmdyYWRlEIEIEhkKFFBsYW5VcGdyYWRlTm90WWVhcmx5EIIIEhgKE0ludmFsaWRTaW'
'duZWRQcmVLZXkQgwg=');

View file

@ -1338,6 +1338,84 @@ class Response_PreKey extends $pb.GeneratedMessage {
void clearPrekey() => clearField(2); void clearPrekey() => clearField(2);
} }
class Response_SignedPreKey extends $pb.GeneratedMessage {
factory Response_SignedPreKey({
$fixnum.Int64? signedPrekeyId,
$core.List<$core.int>? signedPrekey,
$core.List<$core.int>? signedPrekeySignature,
}) {
final $result = create();
if (signedPrekeyId != null) {
$result.signedPrekeyId = signedPrekeyId;
}
if (signedPrekey != null) {
$result.signedPrekey = signedPrekey;
}
if (signedPrekeySignature != null) {
$result.signedPrekeySignature = signedPrekeySignature;
}
return $result;
}
Response_SignedPreKey._() : super();
factory Response_SignedPreKey.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Response_SignedPreKey.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Response.SignedPreKey', package: const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'), createEmptyInstance: create)
..aInt64(1, _omitFieldNames ? '' : 'signedPrekeyId')
..a<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'signedPrekey', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(3, _omitFieldNames ? '' : 'signedPrekeySignature', $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')
Response_SignedPreKey clone() => Response_SignedPreKey()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
Response_SignedPreKey copyWith(void Function(Response_SignedPreKey) updates) => super.copyWith((message) => updates(message as Response_SignedPreKey)) as Response_SignedPreKey;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Response_SignedPreKey create() => Response_SignedPreKey._();
Response_SignedPreKey createEmptyInstance() => create();
static $pb.PbList<Response_SignedPreKey> createRepeated() => $pb.PbList<Response_SignedPreKey>();
@$core.pragma('dart2js:noInline')
static Response_SignedPreKey getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Response_SignedPreKey>(create);
static Response_SignedPreKey? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get signedPrekeyId => $_getI64(0);
@$pb.TagNumber(1)
set signedPrekeyId($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasSignedPrekeyId() => $_has(0);
@$pb.TagNumber(1)
void clearSignedPrekeyId() => clearField(1);
@$pb.TagNumber(2)
$core.List<$core.int> get signedPrekey => $_getN(1);
@$pb.TagNumber(2)
set signedPrekey($core.List<$core.int> v) { $_setBytes(1, v); }
@$pb.TagNumber(2)
$core.bool hasSignedPrekey() => $_has(1);
@$pb.TagNumber(2)
void clearSignedPrekey() => clearField(2);
@$pb.TagNumber(3)
$core.List<$core.int> get signedPrekeySignature => $_getN(2);
@$pb.TagNumber(3)
set signedPrekeySignature($core.List<$core.int> v) { $_setBytes(2, v); }
@$pb.TagNumber(3)
$core.bool hasSignedPrekeySignature() => $_has(2);
@$pb.TagNumber(3)
void clearSignedPrekeySignature() => clearField(3);
}
class Response_UserData extends $pb.GeneratedMessage { class Response_UserData extends $pb.GeneratedMessage {
factory Response_UserData({ factory Response_UserData({
$fixnum.Int64? userId, $fixnum.Int64? userId,
@ -1582,6 +1660,7 @@ enum Response_Ok_Ok {
vouchers, vouchers,
addaccountsinvites, addaccountsinvites,
downloadtokens, downloadtokens,
signedprekey,
notSet notSet
} }
@ -1600,6 +1679,7 @@ class Response_Ok extends $pb.GeneratedMessage {
Response_Vouchers? vouchers, Response_Vouchers? vouchers,
Response_AddAccountsInvites? addaccountsinvites, Response_AddAccountsInvites? addaccountsinvites,
Response_DownloadTokens? downloadtokens, Response_DownloadTokens? downloadtokens,
Response_SignedPreKey? signedprekey,
}) { }) {
final $result = create(); final $result = create();
if (none != null) { if (none != null) {
@ -1641,6 +1721,9 @@ class Response_Ok extends $pb.GeneratedMessage {
if (downloadtokens != null) { if (downloadtokens != null) {
$result.downloadtokens = downloadtokens; $result.downloadtokens = downloadtokens;
} }
if (signedprekey != null) {
$result.signedprekey = signedprekey;
}
return $result; return $result;
} }
Response_Ok._() : super(); Response_Ok._() : super();
@ -1661,10 +1744,11 @@ class Response_Ok extends $pb.GeneratedMessage {
11 : Response_Ok_Ok.vouchers, 11 : Response_Ok_Ok.vouchers,
12 : Response_Ok_Ok.addaccountsinvites, 12 : Response_Ok_Ok.addaccountsinvites,
13 : Response_Ok_Ok.downloadtokens, 13 : Response_Ok_Ok.downloadtokens,
14 : Response_Ok_Ok.signedprekey,
0 : Response_Ok_Ok.notSet 0 : Response_Ok_Ok.notSet
}; };
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Response.Ok', package: const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'), createEmptyInstance: create) static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Response.Ok', package: const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'), createEmptyInstance: create)
..oo(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) ..oo(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
..aOB(1, _omitFieldNames ? '' : 'None', protoName: 'None') ..aOB(1, _omitFieldNames ? '' : 'None', protoName: 'None')
..aInt64(2, _omitFieldNames ? '' : 'userid') ..aInt64(2, _omitFieldNames ? '' : 'userid')
..a<$core.List<$core.int>>(3, _omitFieldNames ? '' : 'authchallenge', $pb.PbFieldType.OY) ..a<$core.List<$core.int>>(3, _omitFieldNames ? '' : 'authchallenge', $pb.PbFieldType.OY)
@ -1678,6 +1762,7 @@ class Response_Ok extends $pb.GeneratedMessage {
..aOM<Response_Vouchers>(11, _omitFieldNames ? '' : 'vouchers', subBuilder: Response_Vouchers.create) ..aOM<Response_Vouchers>(11, _omitFieldNames ? '' : 'vouchers', subBuilder: Response_Vouchers.create)
..aOM<Response_AddAccountsInvites>(12, _omitFieldNames ? '' : 'addaccountsinvites', subBuilder: Response_AddAccountsInvites.create) ..aOM<Response_AddAccountsInvites>(12, _omitFieldNames ? '' : 'addaccountsinvites', subBuilder: Response_AddAccountsInvites.create)
..aOM<Response_DownloadTokens>(13, _omitFieldNames ? '' : 'downloadtokens', subBuilder: Response_DownloadTokens.create) ..aOM<Response_DownloadTokens>(13, _omitFieldNames ? '' : 'downloadtokens', subBuilder: Response_DownloadTokens.create)
..aOM<Response_SignedPreKey>(14, _omitFieldNames ? '' : 'signedprekey', subBuilder: Response_SignedPreKey.create)
..hasRequiredFields = false ..hasRequiredFields = false
; ;
@ -1839,6 +1924,17 @@ class Response_Ok extends $pb.GeneratedMessage {
void clearDownloadtokens() => clearField(13); void clearDownloadtokens() => clearField(13);
@$pb.TagNumber(13) @$pb.TagNumber(13)
Response_DownloadTokens ensureDownloadtokens() => $_ensure(12); Response_DownloadTokens ensureDownloadtokens() => $_ensure(12);
@$pb.TagNumber(14)
Response_SignedPreKey get signedprekey => $_getN(13);
@$pb.TagNumber(14)
set signedprekey(Response_SignedPreKey v) { setField(14, v); }
@$pb.TagNumber(14)
$core.bool hasSignedprekey() => $_has(13);
@$pb.TagNumber(14)
void clearSignedprekey() => clearField(14);
@$pb.TagNumber(14)
Response_SignedPreKey ensureSignedprekey() => $_ensure(13);
} }
enum Response_Response { enum Response_Response {

View file

@ -92,7 +92,7 @@ const Response$json = {
{'1': 'ok', '3': 1, '4': 1, '5': 11, '6': '.server_to_client.Response.Ok', '9': 0, '10': 'ok'}, {'1': 'ok', '3': 1, '4': 1, '5': 11, '6': '.server_to_client.Response.Ok', '9': 0, '10': 'ok'},
{'1': 'error', '3': 2, '4': 1, '5': 14, '6': '.error.ErrorCode', '9': 0, '10': 'error'}, {'1': 'error', '3': 2, '4': 1, '5': 14, '6': '.error.ErrorCode', '9': 0, '10': 'error'},
], ],
'3': [Response_Authenticated$json, Response_Plan$json, Response_Plans$json, Response_AddAccountsInvite$json, Response_AddAccountsInvites$json, Response_Transaction$json, Response_AdditionalAccount$json, Response_Voucher$json, Response_Vouchers$json, Response_PlanBallance$json, Response_Location$json, Response_PreKey$json, Response_UserData$json, Response_UploadToken$json, Response_DownloadTokens$json, Response_Ok$json], '3': [Response_Authenticated$json, Response_Plan$json, Response_Plans$json, Response_AddAccountsInvite$json, Response_AddAccountsInvites$json, Response_Transaction$json, Response_AdditionalAccount$json, Response_Voucher$json, Response_Vouchers$json, Response_PlanBallance$json, Response_Location$json, Response_PreKey$json, Response_SignedPreKey$json, Response_UserData$json, Response_UploadToken$json, Response_DownloadTokens$json, Response_Ok$json],
'4': [Response_TransactionTypes$json], '4': [Response_TransactionTypes$json],
'8': [ '8': [
{'1': 'Response'}, {'1': 'Response'},
@ -228,6 +228,16 @@ const Response_PreKey$json = {
], ],
}; };
@$core.Deprecated('Use responseDescriptor instead')
const Response_SignedPreKey$json = {
'1': 'SignedPreKey',
'2': [
{'1': 'signed_prekey_id', '3': 1, '4': 1, '5': 3, '10': 'signedPrekeyId'},
{'1': 'signed_prekey', '3': 2, '4': 1, '5': 12, '10': 'signedPrekey'},
{'1': 'signed_prekey_signature', '3': 3, '4': 1, '5': 12, '10': 'signedPrekeySignature'},
],
};
@$core.Deprecated('Use responseDescriptor instead') @$core.Deprecated('Use responseDescriptor instead')
const Response_UserData$json = { const Response_UserData$json = {
'1': 'UserData', '1': 'UserData',
@ -283,6 +293,7 @@ const Response_Ok$json = {
{'1': 'vouchers', '3': 11, '4': 1, '5': 11, '6': '.server_to_client.Response.Vouchers', '9': 0, '10': 'vouchers'}, {'1': 'vouchers', '3': 11, '4': 1, '5': 11, '6': '.server_to_client.Response.Vouchers', '9': 0, '10': 'vouchers'},
{'1': 'addaccountsinvites', '3': 12, '4': 1, '5': 11, '6': '.server_to_client.Response.AddAccountsInvites', '9': 0, '10': 'addaccountsinvites'}, {'1': 'addaccountsinvites', '3': 12, '4': 1, '5': 11, '6': '.server_to_client.Response.AddAccountsInvites', '9': 0, '10': 'addaccountsinvites'},
{'1': 'downloadtokens', '3': 13, '4': 1, '5': 11, '6': '.server_to_client.Response.DownloadTokens', '9': 0, '10': 'downloadtokens'}, {'1': 'downloadtokens', '3': 13, '4': 1, '5': 11, '6': '.server_to_client.Response.DownloadTokens', '9': 0, '10': 'downloadtokens'},
{'1': 'signedprekey', '3': 14, '4': 1, '5': 11, '6': '.server_to_client.Response.SignedPreKey', '9': 0, '10': 'signedprekey'},
], ],
'8': [ '8': [
{'1': 'Ok'}, {'1': 'Ok'},
@ -346,33 +357,38 @@ final $typed_data.Uint8List responseDescriptor = $convert.base64Decode(
'1lbnRfZG9uZV91bml4X3RpbWVzdGFtcEIPCg1fYXV0b19yZW5ld2FsQh4KHF9hZGRpdGlvbmFs' '1lbnRfZG9uZV91bml4X3RpbWVzdGFtcEIPCg1fYXV0b19yZW5ld2FsQh4KHF9hZGRpdGlvbmFs'
'X2FjY291bnRfb3duZXJfaWQaTgoITG9jYXRpb24SFgoGY291bnR5GAEgASgJUgZjb3VudHkSFg' 'X2FjY291bnRfb3duZXJfaWQaTgoITG9jYXRpb24SFgoGY291bnR5GAEgASgJUgZjb3VudHkSFg'
'oGcmVnaW9uGAIgASgJUgZyZWdpb24SEgoEY2l0eRgDIAEoCVIEY2l0eRowCgZQcmVLZXkSDgoC' 'oGcmVnaW9uGAIgASgJUgZyZWdpb24SEgoEY2l0eRgDIAEoCVIEY2l0eRowCgZQcmVLZXkSDgoC'
'aWQYASABKANSAmlkEhYKBnByZWtleRgCIAEoDFIGcHJla2V5GrQDCghVc2VyRGF0YRIXCgd1c2' 'aWQYASABKANSAmlkEhYKBnByZWtleRgCIAEoDFIGcHJla2V5GpUBCgxTaWduZWRQcmVLZXkSKA'
'VyX2lkGAEgASgDUgZ1c2VySWQSOwoHcHJla2V5cxgCIAMoCzIhLnNlcnZlcl90b19jbGllbnQu' 'oQc2lnbmVkX3ByZWtleV9pZBgBIAEoA1IOc2lnbmVkUHJla2V5SWQSIwoNc2lnbmVkX3ByZWtl'
'UmVzcG9uc2UuUHJlS2V5UgdwcmVrZXlzEh8KCHVzZXJuYW1lGAcgASgMSABSCHVzZXJuYW1liA' 'eRgCIAEoDFIMc2lnbmVkUHJla2V5EjYKF3NpZ25lZF9wcmVrZXlfc2lnbmF0dXJlGAMgASgMUh'
'EBEjMKE3B1YmxpY19pZGVudGl0eV9rZXkYAyABKAxIAVIRcHVibGljSWRlbnRpdHlLZXmIAQES' 'VzaWduZWRQcmVrZXlTaWduYXR1cmUatAMKCFVzZXJEYXRhEhcKB3VzZXJfaWQYASABKANSBnVz'
'KAoNc2lnbmVkX3ByZWtleRgEIAEoDEgCUgxzaWduZWRQcmVrZXmIAQESOwoXc2lnbmVkX3ByZW' 'ZXJJZBI7CgdwcmVrZXlzGAIgAygLMiEuc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5QcmVLZX'
'tleV9zaWduYXR1cmUYBSABKAxIA1IVc2lnbmVkUHJla2V5U2lnbmF0dXJliAEBEi0KEHNpZ25l' 'lSB3ByZWtleXMSHwoIdXNlcm5hbWUYByABKAxIAFIIdXNlcm5hbWWIAQESMwoTcHVibGljX2lk'
'ZF9wcmVrZXlfaWQYBiABKANIBFIOc2lnbmVkUHJla2V5SWSIAQFCCwoJX3VzZXJuYW1lQhYKFF' 'ZW50aXR5X2tleRgDIAEoDEgBUhFwdWJsaWNJZGVudGl0eUtleYgBARIoCg1zaWduZWRfcHJla2'
'9wdWJsaWNfaWRlbnRpdHlfa2V5QhAKDl9zaWduZWRfcHJla2V5QhoKGF9zaWduZWRfcHJla2V5' 'V5GAQgASgMSAJSDHNpZ25lZFByZWtleYgBARI7ChdzaWduZWRfcHJla2V5X3NpZ25hdHVyZRgF'
'X3NpZ25hdHVyZUITChFfc2lnbmVkX3ByZWtleV9pZBpZCgtVcGxvYWRUb2tlbhIhCgx1cGxvYW' 'IAEoDEgDUhVzaWduZWRQcmVrZXlTaWduYXR1cmWIAQESLQoQc2lnbmVkX3ByZWtleV9pZBgGIA'
'RfdG9rZW4YASABKAxSC3VwbG9hZFRva2VuEicKD2Rvd25sb2FkX3Rva2VucxgCIAMoDFIOZG93' 'EoA0gEUg5zaWduZWRQcmVrZXlJZIgBAUILCglfdXNlcm5hbWVCFgoUX3B1YmxpY19pZGVudGl0'
'bmxvYWRUb2tlbnMaOQoORG93bmxvYWRUb2tlbnMSJwoPZG93bmxvYWRfdG9rZW5zGAEgAygMUg' 'eV9rZXlCEAoOX3NpZ25lZF9wcmVrZXlCGgoYX3NpZ25lZF9wcmVrZXlfc2lnbmF0dXJlQhMKEV'
'5kb3dubG9hZFRva2VucxqoBgoCT2sSFAoETm9uZRgBIAEoCEgAUgROb25lEhgKBnVzZXJpZBgC' '9zaWduZWRfcHJla2V5X2lkGlkKC1VwbG9hZFRva2VuEiEKDHVwbG9hZF90b2tlbhgBIAEoDFIL'
'IAEoA0gAUgZ1c2VyaWQSJgoNYXV0aGNoYWxsZW5nZRgDIAEoDEgAUg1hdXRoY2hhbGxlbmdlEk' 'dXBsb2FkVG9rZW4SJwoPZG93bmxvYWRfdG9rZW5zGAIgAygMUg5kb3dubG9hZFRva2Vucxo5Cg'
'oKC3VwbG9hZHRva2VuGAQgASgLMiYuc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5VcGxvYWRU' '5Eb3dubG9hZFRva2VucxInCg9kb3dubG9hZF90b2tlbnMYASADKAxSDmRvd25sb2FkVG9rZW5z'
'b2tlbkgAUgt1cGxvYWR0b2tlbhJBCgh1c2VyZGF0YRgFIAEoCzIjLnNlcnZlcl90b19jbGllbn' 'GvcGCgJPaxIUCgROb25lGAEgASgISABSBE5vbmUSGAoGdXNlcmlkGAIgASgDSABSBnVzZXJpZB'
'QuUmVzcG9uc2UuVXNlckRhdGFIAFIIdXNlcmRhdGESHgoJYXV0aHRva2VuGAYgASgMSABSCWF1' 'ImCg1hdXRoY2hhbGxlbmdlGAMgASgMSABSDWF1dGhjaGFsbGVuZ2USSgoLdXBsb2FkdG9rZW4Y'
'dGh0b2tlbhJBCghsb2NhdGlvbhgHIAEoCzIjLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuTG' 'BCABKAsyJi5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLlVwbG9hZFRva2VuSABSC3VwbG9hZH'
'9jYXRpb25IAFIIbG9jYXRpb24SUAoNYXV0aGVudGljYXRlZBgIIAEoCzIoLnNlcnZlcl90b19j' 'Rva2VuEkEKCHVzZXJkYXRhGAUgASgLMiMuc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5Vc2Vy'
'bGllbnQuUmVzcG9uc2UuQXV0aGVudGljYXRlZEgAUg1hdXRoZW50aWNhdGVkEjgKBXBsYW5zGA' 'RGF0YUgAUgh1c2VyZGF0YRIeCglhdXRodG9rZW4YBiABKAxIAFIJYXV0aHRva2VuEkEKCGxvY2'
'kgASgLMiAuc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5QbGFuc0gAUgVwbGFucxJNCgxwbGFu' 'F0aW9uGAcgASgLMiMuc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5Mb2NhdGlvbkgAUghsb2Nh'
'YmFsbGFuY2UYCiABKAsyJy5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLlBsYW5CYWxsYW5jZU' 'dGlvbhJQCg1hdXRoZW50aWNhdGVkGAggASgLMiguc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS'
'gAUgxwbGFuYmFsbGFuY2USQQoIdm91Y2hlcnMYCyABKAsyIy5zZXJ2ZXJfdG9fY2xpZW50LlJl' '5BdXRoZW50aWNhdGVkSABSDWF1dGhlbnRpY2F0ZWQSOAoFcGxhbnMYCSABKAsyIC5zZXJ2ZXJf'
'c3BvbnNlLlZvdWNoZXJzSABSCHZvdWNoZXJzEl8KEmFkZGFjY291bnRzaW52aXRlcxgMIAEoCz' 'dG9fY2xpZW50LlJlc3BvbnNlLlBsYW5zSABSBXBsYW5zEk0KDHBsYW5iYWxsYW5jZRgKIAEoCz'
'ItLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuQWRkQWNjb3VudHNJbnZpdGVzSABSEmFkZGFj' 'InLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuUGxhbkJhbGxhbmNlSABSDHBsYW5iYWxsYW5j'
'Y291bnRzaW52aXRlcxJTCg5kb3dubG9hZHRva2VucxgNIAEoCzIpLnNlcnZlcl90b19jbGllbn' 'ZRJBCgh2b3VjaGVycxgLIAEoCzIjLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuVm91Y2hlcn'
'QuUmVzcG9uc2UuRG93bmxvYWRUb2tlbnNIAFIOZG93bmxvYWR0b2tlbnNCBAoCT2silgEKEFRy' 'NIAFIIdm91Y2hlcnMSXwoSYWRkYWNjb3VudHNpbnZpdGVzGAwgASgLMi0uc2VydmVyX3RvX2Ns'
'YW5zYWN0aW9uVHlwZXMSCgoGUmVmdW5kEAASEwoPVm91Y2hlclJlZGVlbWVkEAESEgoOVm91Y2' 'aWVudC5SZXNwb25zZS5BZGRBY2NvdW50c0ludml0ZXNIAFISYWRkYWNjb3VudHNpbnZpdGVzEl'
'hlckNyZWF0ZWQQAhIICgRDYXNoEAMSDwoLUGxhblVwZ3JhZGUQBBILCgdVbmtub3duEAUSFAoQ' 'MKDmRvd25sb2FkdG9rZW5zGA0gASgLMikuc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5Eb3du'
'VGhhbmtzRm9yVGVzdGluZxAGEg8KC0F1dG9SZW5ld2FsEAdCCgoIUmVzcG9uc2U='); 'bG9hZFRva2Vuc0gAUg5kb3dubG9hZHRva2VucxJNCgxzaWduZWRwcmVrZXkYDiABKAsyJy5zZX'
'J2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLlNpZ25lZFByZUtleUgAUgxzaWduZWRwcmVrZXlCBAoC'
'T2silgEKEFRyYW5zYWN0aW9uVHlwZXMSCgoGUmVmdW5kEAASEwoPVm91Y2hlclJlZGVlbWVkEA'
'ESEgoOVm91Y2hlckNyZWF0ZWQQAhIICgRDYXNoEAMSDwoLUGxhblVwZ3JhZGUQBBILCgdVbmtu'
'b3duEAUSFAoQVGhhbmtzRm9yVGVzdGluZxAGEg8KC0F1dG9SZW5ld2FsEAdCCgoIUmVzcG9uc2'
'U=');

View file

@ -83,6 +83,7 @@ class ApiService {
notifyContactsAboutProfileChange(); notifyContactsAboutProfileChange();
twonlyDB.markUpdated(); twonlyDB.markUpdated();
syncFlameCounters(); syncFlameCounters();
signalHandleNewServerConnection();
} }
} }
@ -329,7 +330,7 @@ class ApiService {
final challenge = result.value.authchallenge; final challenge = result.value.authchallenge;
final privKey = await getSignalPrivateIdentityKey(); final privKey = (await getSignalIdentityKeyPair())?.getPrivateKey();
if (privKey == null) return; if (privKey == null) return;
final random = getRandomUint8List(32); final random = getRandomUint8List(32);
final signature = sign(privKey.serialize(), challenge, random); final signature = sign(privKey.serialize(), challenge, random);
@ -544,6 +545,20 @@ class ApiService {
return await sendRequestSync(req); return await sendRequestSync(req);
} }
Future<Result> updateSignedPreKey(
int signedPreKeyId,
Uint8List signedPreKey,
Uint8List signedPreKeySignature,
) async {
var get = ApplicationData_UpdateSignedPreKey()
..signedPrekeyId = Int64(signedPreKeyId)
..signedPrekey = signedPreKey
..signedPrekeySignature = signedPreKeySignature;
var appData = ApplicationData()..updatesignedprekey = get;
var req = createClientToServerFromApplicationData(appData);
return await sendRequestSync(req);
}
Future<Result> sendTextMessage( Future<Result> sendTextMessage(
int target, Uint8List msg, List<int>? pushData) async { int target, Uint8List msg, List<int>? pushData) async {
var testMessage = ApplicationData_TextMessage() var testMessage = ApplicationData_TextMessage()

View file

@ -19,7 +19,7 @@ import 'package:twonly/src/services/api/utils.dart';
import 'package:twonly/src/services/api/media_received.dart'; import 'package:twonly/src/services/api/media_received.dart';
import 'package:twonly/src/services/notification.service.dart'; import 'package:twonly/src/services/notification.service.dart';
import 'package:twonly/src/services/signal/encryption.signal.dart'; import 'package:twonly/src/services/signal/encryption.signal.dart';
import 'package:twonly/src/services/signal/utils.signal.dart'; import 'package:twonly/src/services/signal/identity.signal.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
final lockHandleServerMessage = Mutex(); final lockHandleServerMessage = Mutex();

View file

@ -0,0 +1,2 @@
// multi device support is not planned, so just set this to one
const int defaultDeviceId = 1;

View file

@ -4,19 +4,85 @@ import 'dart:typed_data';
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
import 'package:twonly/src/model/json/message.dart'; import 'package:twonly/src/model/json/message.dart';
import 'package:twonly/src/database/signal/connect_signal_protocol_store.dart'; import 'package:twonly/src/database/signal/connect_signal_protocol_store.dart';
import 'package:twonly/src/services/signal/consts.signal.dart';
import 'package:twonly/src/services/signal/utils.signal.dart'; import 'package:twonly/src/services/signal/utils.signal.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
// Future<void> deleteSession(String userId) async {
// await mixinSignalProtocolStore.sessionStore.sessionDao
// .deleteSessionsByAddress(userId);
// }
// Future<void> processSession(String userId, PreKeyBundle preKeyBundle) async {
// final signalProtocolAddress = SignalProtocolAddress(
// userId,
// preKeyBundle.getDeviceId(),
// );
// final sessionBuilder = SessionBuilder.fromSignalStore(
// mixinSignalProtocolStore,
// signalProtocolAddress,
// );
// try {
// await sessionBuilder.processPreKeyBundle(preKeyBundle);
// } on UntrustedIdentityException {
// await mixinSignalProtocolStore.removeIdentity(signalProtocolAddress);
// await sessionBuilder.processPreKeyBundle(preKeyBundle);
// }
// }
// Future<bool> checkSignalSession(String recipientId, String sessionId) async {
// final contains = await signalProtocol.containsSession(
// recipientId,
// deviceId: sessionId.getDeviceId(),
// );
// if (!contains) {
// final requestKeys = <BlazeMessageParamSession>[
// BlazeMessageParamSession(userId: recipientId, sessionId: sessionId),
// ];
// final blazeMessage = createConsumeSessionSignalKeys(
// createConsumeSignalKeysParam(requestKeys),
// );
// final data = (await signalKeysChannel(blazeMessage))?.data;
// if (data == null) {
// return false;
// }
// final keys = List<SignalKey>.from(
// (data as List<dynamic>).map(
// (e) => SignalKey.fromJson(e as Map<String, dynamic>),
// ),
// );
// if (keys.isNotEmpty) {
// final preKeyBundle = keys.first.createPreKeyBundle();
// await signalProtocol.processSession(recipientId, preKeyBundle);
// } else {
// return false;
// }
// }
// return true;
// }
Future<Uint8List?> signalEncryptMessage(int target, MessageJson msg) async { Future<Uint8List?> signalEncryptMessage(int target, MessageJson msg) async {
try { try {
ConnectSignalProtocolStore signalStore = (await getSignalStore())!; ConnectSignalProtocolStore signalStore = (await getSignalStore())!;
final address = SignalProtocolAddress(target.toString(), defaultDeviceId);
SessionCipher session = SessionCipher.fromStore( SessionCipher session = SessionCipher.fromStore(signalStore, address);
signalStore, SignalProtocolAddress(target.toString(), defaultDeviceId));
final SessionRecord sessionRecord =
await signalStore.sessionStore.loadSession(address);
if (!sessionRecord.sessionState.hasUnacknowledgedPreKeyMessage()) {
Log.info("There are now pre keys any more... load new...");
}
// sessionRecord.sessionState.sign
// session.
final ciphertext = await session.encrypt( final ciphertext = await session.encrypt(
Uint8List.fromList(gzip.encode(utf8.encode(jsonEncode(msg.toJson()))))); Uint8List.fromList(gzip.encode(utf8.encode(jsonEncode(msg.toJson())))),
);
var b = BytesBuilder(); var b = BytesBuilder();
b.add(ciphertext.serialize()); b.add(ciphertext.serialize());

View file

@ -1,34 +1,81 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
import 'package:logging/logging.dart'; import 'package:twonly/globals.dart';
import 'package:twonly/src/constants/secure_storage_keys.dart';
import 'package:twonly/src/model/json/signal_identity.dart'; import 'package:twonly/src/model/json/signal_identity.dart';
import 'package:twonly/src/database/signal/connect_signal_protocol_store.dart'; import 'package:twonly/src/database/signal/connect_signal_protocol_store.dart';
import 'package:twonly/src/model/json/userdata.dart';
import 'package:twonly/src/services/api/utils.dart';
import 'package:twonly/src/services/signal/consts.signal.dart';
import 'package:twonly/src/services/signal/utils.signal.dart';
import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/storage.dart';
const int defaultDeviceId = 1; Future<IdentityKeyPair?> getSignalIdentityKeyPair() async {
Future<ECPrivateKey?> getSignalPrivateIdentityKey() async {
final signalIdentity = await getSignalIdentity(); final signalIdentity = await getSignalIdentity();
if (signalIdentity == null) { if (signalIdentity == null) return null;
return null; return IdentityKeyPair.fromSerialized(signalIdentity.identityKeyPairU8List);
} }
final IdentityKeyPair identityKeyPair = // This function runs after the clients authenticated with the server.
IdentityKeyPair.fromSerialized(signalIdentity.identityKeyPairU8List); // It then checks if it should update a new session key
Future signalHandleNewServerConnection() async {
final UserData? user = await getUser();
if (user == null) return;
if (user.signalLastSignedPreKeyUpdated != null) {
DateTime fortyEightHoursAgo = DateTime.now().subtract(Duration(hours: 48));
bool isYoungerThan48Hours =
(user.signalLastSignedPreKeyUpdated!).isAfter(fortyEightHoursAgo);
if (isYoungerThan48Hours) {
// The key does live for 48 hours then it expires and a new key is generated.
return;
}
}
SignedPreKeyRecord? signedPreKey = await _getNewSignalSignedPreKey();
if (signedPreKey == null) {
Log.error("could not generate a new signed pre key!");
return;
}
user.signalLastSignedPreKeyUpdated = DateTime.now();
await updateUser(user);
Result res = await apiService.updateSignedPreKey(
signedPreKey.id,
signedPreKey.getKeyPair().publicKey.serialize(),
signedPreKey.signature,
);
if (res.isError) {
Log.error("could not update the signed pre key: ${res.error}");
final UserData? user = await getUser();
if (user == null) return;
user.signalLastSignedPreKeyUpdated = null;
await updateUser(user);
} else {
Log.info("updated signed pre key");
}
}
return identityKeyPair.getPrivateKey(); Future<List<PreKeyRecord>> signalGetPreKeys() async {
final preKeys = generatePreKeys(0, 200);
final signalStore = await getSignalStore();
if (signalStore == null) return [];
for (final p in preKeys) {
await signalStore.preKeyStore.storePreKey(p.id, p);
}
return preKeys;
} }
Future<SignalIdentity?> getSignalIdentity() async { Future<SignalIdentity?> getSignalIdentity() async {
try { try {
final storage = FlutterSecureStorage(); final storage = FlutterSecureStorage();
final signalIdentityJson = await storage.read(key: "signal_identity"); final signalIdentityJson =
await storage.read(key: SecureStorageKeys.signalIdentity);
if (signalIdentityJson == null) { if (signalIdentityJson == null) {
return null; return null;
} }
return SignalIdentity.fromJson(jsonDecode(signalIdentityJson)); return SignalIdentity.fromJson(jsonDecode(signalIdentityJson));
} catch (e) { } catch (e) {
Logger("signal.dart/getSignalIdentity").shout(e); Log.error("could not load signal identity: $e");
return null; return null;
} }
} }
@ -36,7 +83,10 @@ Future<SignalIdentity?> getSignalIdentity() async {
Future createIfNotExistsSignalIdentity() async { Future createIfNotExistsSignalIdentity() async {
final storage = FlutterSecureStorage(); final storage = FlutterSecureStorage();
final signalIdentity = await storage.read(key: "signal_identity"); final signalIdentity = await storage.read(
key: SecureStorageKeys.signalIdentity,
);
if (signalIdentity != null) { if (signalIdentity != null) {
return; return;
} }
@ -58,5 +108,25 @@ Future createIfNotExistsSignalIdentity() async {
); );
await storage.write( await storage.write(
key: "signal_identity", value: jsonEncode(storedSignalIdentity)); key: SecureStorageKeys.signalIdentity,
value: jsonEncode(storedSignalIdentity),
);
}
Future<SignedPreKeyRecord?> _getNewSignalSignedPreKey() async {
final identityKeyPair = await getSignalIdentityKeyPair();
if (identityKeyPair == null) return null;
final signalStore = await getSignalStore();
if (signalStore == null) return null;
int signedPreKeyId = await signalStore.signedPreKeyStore.getNextKeyId();
final SignedPreKeyRecord signedPreKey = generateSignedPreKey(
identityKeyPair,
signedPreKeyId,
);
await signalStore.storeSignedPreKey(signedPreKeyId, signedPreKey);
return signedPreKey;
} }

View file

@ -3,52 +3,63 @@ import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
import 'package:twonly/src/model/json/userdata.dart'; import 'package:twonly/src/model/json/userdata.dart';
import 'package:twonly/src/model/protobuf/api/server_to_client.pb.dart'; import 'package:twonly/src/model/protobuf/api/server_to_client.pb.dart';
import 'package:twonly/src/database/signal/connect_signal_protocol_store.dart'; import 'package:twonly/src/database/signal/connect_signal_protocol_store.dart';
import 'package:twonly/src/services/signal/consts.signal.dart';
import 'package:twonly/src/services/signal/utils.signal.dart'; import 'package:twonly/src/services/signal/utils.signal.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/utils/storage.dart';
const int defaultDeviceId = 1;
Future<bool> createNewSignalSession(Response_UserData userData) async { Future<bool> createNewSignalSession(Response_UserData userData) async {
final int userId = userData.userId.toInt();
SignalProtocolAddress targetAddress =
SignalProtocolAddress(userId.toString(), defaultDeviceId);
SignalProtocolStore? signalStore = await getSignalStore(); SignalProtocolStore? signalStore = await getSignalStore();
if (signalStore == null) { if (signalStore == null) {
return false; return false;
} }
SessionBuilder sessionBuilder = SignalProtocolAddress targetAddress = SignalProtocolAddress(
SessionBuilder.fromSignalStore(signalStore, targetAddress); userData.userId.toString(),
defaultDeviceId,
);
SessionBuilder sessionBuilder = SessionBuilder.fromSignalStore(
signalStore,
targetAddress,
);
ECPublicKey? tempPrePublicKey; ECPublicKey? tempPrePublicKey;
int? tempPreKeyId; int? tempPreKeyId;
if (userData.prekeys.isNotEmpty) { if (userData.prekeys.isNotEmpty) {
tempPrePublicKey = Curve.decodePoint( tempPrePublicKey = Curve.decodePoint(
DjbECPublicKey(Uint8List.fromList(userData.prekeys.first.prekey)) DjbECPublicKey(
.serialize(), Uint8List.fromList(userData.prekeys.first.prekey),
1); ).serialize(),
1,
);
tempPreKeyId = userData.prekeys.first.id.toInt(); tempPreKeyId = userData.prekeys.first.id.toInt();
} }
int tempSignedPreKeyId = userData.signedPrekeyId.toInt(); int tempSignedPreKeyId = userData.signedPrekeyId.toInt();
ECPublicKey? tempSignedPreKeyPublic = Curve.decodePoint( ECPublicKey? tempSignedPreKeyPublic = Curve.decodePoint(
DjbECPublicKey(Uint8List.fromList(userData.signedPrekey)).serialize(), 1); DjbECPublicKey(Uint8List.fromList(userData.signedPrekey)).serialize(),
1,
);
Uint8List? tempSignedPreKeySignature = Uint8List? tempSignedPreKeySignature = Uint8List.fromList(
Uint8List.fromList(userData.signedPrekeySignature); userData.signedPrekeySignature,
);
IdentityKey tempIdentityKey = IdentityKey(Curve.decodePoint( IdentityKey tempIdentityKey = IdentityKey(
Curve.decodePoint(
DjbECPublicKey(Uint8List.fromList(userData.publicIdentityKey)) DjbECPublicKey(Uint8List.fromList(userData.publicIdentityKey))
.serialize(), .serialize(),
1)); 1,
),
);
PreKeyBundle preKeyBundle = PreKeyBundle( PreKeyBundle preKeyBundle = PreKeyBundle(
userData.userId.toInt(), userData.userId.toInt(),
1, defaultDeviceId,
tempPreKeyId, tempPreKeyId,
tempPrePublicKey, tempPrePublicKey,
tempSignedPreKeyId, tempSignedPreKeyId,

View file

@ -3,8 +3,6 @@ import 'package:twonly/src/model/json/signal_identity.dart';
import 'package:twonly/src/database/signal/connect_signal_protocol_store.dart'; import 'package:twonly/src/database/signal/connect_signal_protocol_store.dart';
import 'package:twonly/src/services/signal/identity.signal.dart'; import 'package:twonly/src/services/signal/identity.signal.dart';
const int defaultDeviceId = 1;
Future<ConnectSignalProtocolStore?> getSignalStore() async { Future<ConnectSignalProtocolStore?> getSignalStore() async {
return await getSignalStoreFromIdentity((await getSignalIdentity())!); return await getSignalStoreFromIdentity((await getSignalIdentity())!);
} }
@ -17,13 +15,3 @@ Future<ConnectSignalProtocolStore> getSignalStoreFromIdentity(
return ConnectSignalProtocolStore( return ConnectSignalProtocolStore(
identityKeyPair, signalIdentity.registrationId.toInt()); identityKeyPair, signalIdentity.registrationId.toInt());
} }
Future<List<PreKeyRecord>> signalGetPreKeys() async {
final preKeys = generatePreKeys(0, 200);
final signalStore = await getSignalStore();
if (signalStore == null) return [];
for (final p in preKeys) {
await signalStore.preKeyStore.storePreKey(p.id, p);
}
return preKeys;
}