mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 09:28:41 +00:00
move files
This commit is contained in:
parent
85c0f32f21
commit
b06c2e1cc8
13 changed files with 356 additions and 204 deletions
106
lib/src/model/json/message.dart
Normal file
106
lib/src/model/json/message.dart
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:twonly/src/utils/json.dart';
|
||||
part 'message.g.dart';
|
||||
|
||||
enum MessageKind { textMessage, image, video, contactRequest }
|
||||
|
||||
// so _$MessageKindEnumMap gets generated
|
||||
@JsonSerializable()
|
||||
class _MessageKind {
|
||||
MessageKind? kind;
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class Message {
|
||||
@Int64Converter()
|
||||
final Int64 fromUserId;
|
||||
final MessageKind kind;
|
||||
final MessageContent? content;
|
||||
DateTime timestamp;
|
||||
|
||||
Message(
|
||||
{required this.fromUserId,
|
||||
required this.kind,
|
||||
this.content,
|
||||
required this.timestamp});
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Message(kind: $kind, content: $content, timestamp: $timestamp)';
|
||||
}
|
||||
|
||||
Message fromJson(Map<String, dynamic> json) {
|
||||
dynamic content;
|
||||
MessageKind kind = $enumDecode(_$MessageKindEnumMap, json['kind']);
|
||||
switch (kind) {
|
||||
case MessageKind.textMessage:
|
||||
content = TextContent.fromJson(json["content"]);
|
||||
break;
|
||||
case MessageKind.image:
|
||||
content = ImageContent.fromJson(json["content"]);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
return Message(
|
||||
fromUserId: const Int64Converter().fromJson(json['fromUserId'] as String),
|
||||
kind: kind,
|
||||
timestamp: DateTime.parse(json['timestamp'] as String),
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson(Message instance) {
|
||||
var json = <String, dynamic>{
|
||||
'fromUserId': const Int64Converter().toJson(instance.fromUserId),
|
||||
'kind': _$MessageKindEnumMap[instance.kind]!,
|
||||
'timestamp': instance.timestamp.toIso8601String(),
|
||||
'content': instance.content
|
||||
};
|
||||
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class MessageContent {
|
||||
MessageContent();
|
||||
factory MessageContent.fromJson(Map<String, dynamic> json) {
|
||||
return TextContent("");
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson();
|
||||
}
|
||||
// factory MessageContent.fromJson(Map<String, dynamic> json) =>
|
||||
// _$MessageContentFromJson(json);
|
||||
|
||||
@JsonSerializable()
|
||||
class TextContent extends MessageContent {
|
||||
final String text;
|
||||
|
||||
TextContent(this.text);
|
||||
|
||||
factory TextContent.fromJson(Map<String, dynamic> json) =>
|
||||
_$TextContentFromJson(json);
|
||||
@override
|
||||
Map<String, dynamic> toJson() => _$TextContentToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class ImageContent extends MessageContent {
|
||||
final String imageUrl;
|
||||
|
||||
ImageContent(this.imageUrl);
|
||||
|
||||
factory ImageContent.fromJson(Map<String, dynamic> json) =>
|
||||
_$ImageContentFromJson(json);
|
||||
@override
|
||||
Map<String, dynamic> toJson() => _$ImageContentToJson(this);
|
||||
}
|
||||
|
||||
// @JsonSerializable()
|
||||
// class VideoContent extends MessageContent {
|
||||
// final String videoUrl;
|
||||
|
||||
// VideoContent(this.videoUrl);
|
||||
// }
|
||||
56
lib/src/model/json/message.g.dart
Normal file
56
lib/src/model/json/message.g.dart
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'message.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_MessageKind _$MessageKindFromJson(Map<String, dynamic> json) => _MessageKind()
|
||||
..kind = $enumDecodeNullable(_$MessageKindEnumMap, json['kind']);
|
||||
|
||||
Map<String, dynamic> _$MessageKindToJson(_MessageKind instance) =>
|
||||
<String, dynamic>{
|
||||
'kind': _$MessageKindEnumMap[instance.kind],
|
||||
};
|
||||
|
||||
const _$MessageKindEnumMap = {
|
||||
MessageKind.textMessage: 'textMessage',
|
||||
MessageKind.image: 'image',
|
||||
MessageKind.video: 'video',
|
||||
MessageKind.contactRequest: 'contactRequest',
|
||||
};
|
||||
|
||||
Message _$MessageFromJson(Map<String, dynamic> json) => Message(
|
||||
fromUserId: const Int64Converter().fromJson(json['fromUserId'] as String),
|
||||
kind: $enumDecode(_$MessageKindEnumMap, json['kind']),
|
||||
content: json['content'] == null
|
||||
? null
|
||||
: MessageContent.fromJson(json['content'] as Map<String, dynamic>),
|
||||
timestamp: DateTime.parse(json['timestamp'] as String),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$MessageToJson(Message instance) => <String, dynamic>{
|
||||
'fromUserId': const Int64Converter().toJson(instance.fromUserId),
|
||||
'kind': _$MessageKindEnumMap[instance.kind]!,
|
||||
'content': instance.content,
|
||||
'timestamp': instance.timestamp.toIso8601String(),
|
||||
};
|
||||
|
||||
TextContent _$TextContentFromJson(Map<String, dynamic> json) => TextContent(
|
||||
json['text'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$TextContentToJson(TextContent instance) =>
|
||||
<String, dynamic>{
|
||||
'text': instance.text,
|
||||
};
|
||||
|
||||
ImageContent _$ImageContentFromJson(Map<String, dynamic> json) => ImageContent(
|
||||
json['imageUrl'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ImageContentToJson(ImageContent instance) =>
|
||||
<String, dynamic>{
|
||||
'imageUrl': instance.imageUrl,
|
||||
};
|
||||
|
|
@ -1,22 +1,8 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:twonly/src/model/user_data_json.dart';
|
||||
part 'signal_identity_json.g.dart';
|
||||
|
||||
class Uint8ListConverter implements JsonConverter<Uint8List, String> {
|
||||
const Uint8ListConverter();
|
||||
@override
|
||||
Uint8List fromJson(String json) {
|
||||
return base64Decode(json);
|
||||
}
|
||||
|
||||
@override
|
||||
String toJson(Uint8List object) {
|
||||
return base64Encode(object);
|
||||
}
|
||||
}
|
||||
import 'package:twonly/src/utils/json.dart';
|
||||
part 'signal_identity.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class SignalIdentity {
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'signal_identity_json.dart';
|
||||
part of 'signal_identity.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
|
|
@ -1,20 +1,7 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
part 'user_data_json.g.dart';
|
||||
|
||||
class Int64Converter implements JsonConverter<Int64, String> {
|
||||
const Int64Converter();
|
||||
|
||||
@override
|
||||
Int64 fromJson(String json) {
|
||||
return Int64.parseInt(json);
|
||||
}
|
||||
|
||||
@override
|
||||
String toJson(Int64 object) {
|
||||
return object.toString();
|
||||
}
|
||||
}
|
||||
import 'package:twonly/src/utils/json.dart';
|
||||
part 'user_data.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class UserData {
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'user_data_json.dart';
|
||||
part of 'user_data.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
|
|
@ -3,17 +3,18 @@ import 'dart:math';
|
|||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
|
||||
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:twonly/src/proto/api/client_to_server.pb.dart' as client;
|
||||
import 'package:twonly/src/proto/api/client_to_server.pbserver.dart';
|
||||
import 'package:twonly/src/proto/api/error.pb.dart';
|
||||
import 'package:twonly/src/proto/api/server_to_client.pb.dart' as server;
|
||||
import 'package:twonly/src/signal/signal_helper.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
// ignore: library_prefixes
|
||||
import 'package:twonly/src/utils/signal.dart' as SignalHelper;
|
||||
import 'package:web_socket_channel/io.dart';
|
||||
// ignore: implementation_imports
|
||||
import 'package:libsignal_protocol_dart/src/ecc/ed25519.dart';
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,8 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
import 'dart:typed_data';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:twonly/src/model/signal_identity_json.dart';
|
||||
import 'package:twonly/src/proto/api/server_to_client.pb.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
|
||||
import 'package:twonly/src/utils/signal.dart';
|
||||
import 'connect_sender_key_store.dart';
|
||||
import 'connect_signal_protocol_store.dart';
|
||||
|
||||
|
|
@ -23,8 +18,8 @@ class SignalDataModel {
|
|||
// Session validation
|
||||
Future<Fingerprint?> generateSessionFingerPrint(String target) async {
|
||||
try {
|
||||
IdentityKey? targetIdentity = await signalStore.getIdentity(
|
||||
SignalProtocolAddress(target, SignalHelper.defaultDeviceId));
|
||||
IdentityKey? targetIdentity = await signalStore
|
||||
.getIdentity(SignalProtocolAddress(target, defaultDeviceId));
|
||||
if (targetIdentity != null) {
|
||||
final generator = NumericFingerprintGenerator(5200);
|
||||
final localFingerprint = generator.createFor(
|
||||
|
|
@ -48,8 +43,8 @@ class SignalDataModel {
|
|||
|
||||
Future<String?> getEncryptedText(String text, String target) async {
|
||||
try {
|
||||
SessionCipher session = SessionCipher.fromStore(signalStore,
|
||||
SignalProtocolAddress(target, SignalHelper.defaultDeviceId));
|
||||
SessionCipher session = SessionCipher.fromStore(
|
||||
signalStore, SignalProtocolAddress(target, defaultDeviceId));
|
||||
final ciphertext =
|
||||
await session.encrypt(Uint8List.fromList(utf8.encode(text)));
|
||||
Map<String, dynamic> data = {
|
||||
|
|
@ -65,8 +60,8 @@ class SignalDataModel {
|
|||
|
||||
Future<String?> getDecryptedText(String source, String msg) async {
|
||||
try {
|
||||
SessionCipher session = SessionCipher.fromStore(signalStore,
|
||||
SignalProtocolAddress(source, SignalHelper.defaultDeviceId));
|
||||
SessionCipher session = SessionCipher.fromStore(
|
||||
signalStore, SignalProtocolAddress(source, defaultDeviceId));
|
||||
Map data = jsonDecode(msg);
|
||||
if (data["type"] == CiphertextMessage.prekeyType) {
|
||||
PreKeySignalMessage pre =
|
||||
|
|
@ -89,156 +84,3 @@ class SignalDataModel {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int userIdToRegistrationId(List<int> userId) {
|
||||
int result = 0;
|
||||
for (int i = 8; i < 16; i++) {
|
||||
result = (result << 8) | userId[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
String uint8ListToHex(List<int> list) {
|
||||
final StringBuffer hexBuffer = StringBuffer();
|
||||
for (int byte in list) {
|
||||
hexBuffer.write(byte.toRadixString(16).padLeft(2, '0'));
|
||||
}
|
||||
return hexBuffer.toString().toUpperCase();
|
||||
}
|
||||
|
||||
class SignalHelper {
|
||||
static const int defaultDeviceId = 1;
|
||||
|
||||
static Future<ECPrivateKey?> getPrivateKey() async {
|
||||
final signalIdentity = await getSignalIdentity();
|
||||
if (signalIdentity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final IdentityKeyPair identityKeyPair =
|
||||
IdentityKeyPair.fromSerialized(signalIdentity.identityKeyPairU8List);
|
||||
|
||||
return identityKeyPair.getPrivateKey();
|
||||
}
|
||||
|
||||
static Future<bool> addNewContact(Response_UserData userData) async {
|
||||
final Int64 userId = userData.userId;
|
||||
|
||||
SignalProtocolAddress targetAddress =
|
||||
SignalProtocolAddress(userId.toString(), SignalHelper.defaultDeviceId);
|
||||
|
||||
SignalProtocolStore? signalStore = await SignalHelper.getSignalStore();
|
||||
if (signalStore == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SessionBuilder sessionBuilder =
|
||||
SessionBuilder.fromSignalStore(signalStore, targetAddress);
|
||||
|
||||
ECPublicKey? tempPrePublicKey;
|
||||
int? tempPreKeyId;
|
||||
if (userData.prekeys.isNotEmpty) {
|
||||
tempPrePublicKey = Curve.decodePoint(
|
||||
DjbECPublicKey(Uint8List.fromList(userData.prekeys.first.prekey))
|
||||
.serialize(),
|
||||
1);
|
||||
tempPreKeyId = userData.prekeys.first.id.toInt();
|
||||
}
|
||||
// Signed pre key calculation
|
||||
int tempSignedPreKeyId = userData.signedPrekeyId.toInt();
|
||||
// Map? tempSignedPreKey = remoteBundle["signedPreKey"];
|
||||
ECPublicKey? tempSignedPreKeyPublic;
|
||||
Uint8List? tempSignedPreKeySignature;
|
||||
// if (tempSignedPreKey != null) {
|
||||
tempSignedPreKeyPublic = Curve.decodePoint(
|
||||
DjbECPublicKey(Uint8List.fromList(userData.signedPrekey)).serialize(),
|
||||
1);
|
||||
tempSignedPreKeySignature =
|
||||
Uint8List.fromList(userData.signedPrekeySignature);
|
||||
// }
|
||||
// Identity key calculation
|
||||
IdentityKey tempIdentityKey = IdentityKey(Curve.decodePoint(
|
||||
DjbECPublicKey(Uint8List.fromList(userData.publicIdentityKey))
|
||||
.serialize(),
|
||||
1));
|
||||
PreKeyBundle preKeyBundle = PreKeyBundle(
|
||||
userData.userId.toInt(),
|
||||
1,
|
||||
tempPreKeyId,
|
||||
tempPrePublicKey,
|
||||
tempSignedPreKeyId,
|
||||
tempSignedPreKeyPublic,
|
||||
tempSignedPreKeySignature,
|
||||
tempIdentityKey,
|
||||
);
|
||||
|
||||
try {
|
||||
await sessionBuilder.processPreKeyBundle(preKeyBundle);
|
||||
return true;
|
||||
} catch (e) {
|
||||
Logger("signal_helper").shout("Error: $e");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<ConnectSignalProtocolStore?> getSignalStore() async {
|
||||
return await getSignalStoreFromIdentity((await getSignalIdentity())!);
|
||||
}
|
||||
|
||||
static Future<SignalIdentity?> getSignalIdentity() async {
|
||||
final storage = getSecureStorage();
|
||||
final signalIdentityJson = await storage.read(key: "signal_identity");
|
||||
if (signalIdentityJson == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return SignalIdentity.fromJson(jsonDecode(signalIdentityJson));
|
||||
}
|
||||
|
||||
static Future<ConnectSignalProtocolStore> getSignalStoreFromIdentity(
|
||||
SignalIdentity signalIdentity) async {
|
||||
final IdentityKeyPair identityKeyPair =
|
||||
IdentityKeyPair.fromSerialized(signalIdentity.identityKeyPairU8List);
|
||||
|
||||
return ConnectSignalProtocolStore(
|
||||
identityKeyPair, signalIdentity.registrationId.toInt());
|
||||
}
|
||||
|
||||
static Future<List<PreKeyRecord>> getPreKeys() 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;
|
||||
}
|
||||
|
||||
static Future createIfNotExistsSignalIdentity() async {
|
||||
final storage = getSecureStorage();
|
||||
|
||||
final signalIdentity = await storage.read(key: "signal_identity");
|
||||
if (signalIdentity != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final identityKeyPair = generateIdentityKeyPair();
|
||||
final registrationId = generateRegistrationId(true);
|
||||
|
||||
ConnectSignalProtocolStore signalStore =
|
||||
ConnectSignalProtocolStore(identityKeyPair, registrationId);
|
||||
|
||||
final signedPreKey =
|
||||
generateSignedPreKey(identityKeyPair, SignalHelper.defaultDeviceId);
|
||||
|
||||
await signalStore.signedPreKeyStore
|
||||
.storeSignedPreKey(signedPreKey.id, signedPreKey);
|
||||
|
||||
final storedSignalIdentity = SignalIdentity(
|
||||
identityKeyPairU8List: identityKeyPair.serialize(),
|
||||
registrationId: Int64(registrationId));
|
||||
|
||||
await storage.write(
|
||||
key: "signal_identity", value: jsonEncode(storedSignalIdentity));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ import 'dart:convert';
|
|||
import 'package:logging/logging.dart';
|
||||
import 'package:twonly/main.dart';
|
||||
import 'package:twonly/src/model/contacts_model.dart';
|
||||
import 'package:twonly/src/signal/signal_helper.dart';
|
||||
import 'package:twonly/src/providers/api_provider.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/model/user_data_json.dart';
|
||||
// ignore: library_prefixes
|
||||
import 'package:twonly/src/utils/signal.dart' as SignalHelper;
|
||||
import 'package:twonly/src/model/json/user_data.dart';
|
||||
|
||||
Future<bool> addNewContact(String username) async {
|
||||
final res = await apiProvider.getUserData(username);
|
||||
|
|
|
|||
31
lib/src/utils/json.dart
Normal file
31
lib/src/utils/json.dart
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
class Int64Converter implements JsonConverter<Int64, String> {
|
||||
const Int64Converter();
|
||||
|
||||
@override
|
||||
Int64 fromJson(String json) {
|
||||
return Int64.parseInt(json);
|
||||
}
|
||||
|
||||
@override
|
||||
String toJson(Int64 object) {
|
||||
return object.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class Uint8ListConverter implements JsonConverter<Uint8List, String> {
|
||||
const Uint8ListConverter();
|
||||
@override
|
||||
Uint8List fromJson(String json) {
|
||||
return base64Decode(json);
|
||||
}
|
||||
|
||||
@override
|
||||
String toJson(Uint8List object) {
|
||||
return base64Encode(object);
|
||||
}
|
||||
}
|
||||
142
lib/src/utils/signal.dart
Normal file
142
lib/src/utils/signal.dart
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:twonly/src/model/json/signal_identity.dart';
|
||||
import 'package:twonly/src/proto/api/server_to_client.pb.dart';
|
||||
import 'package:twonly/src/signal/connect_signal_protocol_store.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
|
||||
const int defaultDeviceId = 1;
|
||||
|
||||
Future<ECPrivateKey?> getPrivateKey() async {
|
||||
final signalIdentity = await getSignalIdentity();
|
||||
if (signalIdentity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final IdentityKeyPair identityKeyPair =
|
||||
IdentityKeyPair.fromSerialized(signalIdentity.identityKeyPairU8List);
|
||||
|
||||
return identityKeyPair.getPrivateKey();
|
||||
}
|
||||
|
||||
Future<bool> addNewContact(Response_UserData userData) async {
|
||||
final Int64 userId = userData.userId;
|
||||
|
||||
SignalProtocolAddress targetAddress =
|
||||
SignalProtocolAddress(userId.toString(), defaultDeviceId);
|
||||
|
||||
SignalProtocolStore? signalStore = await getSignalStore();
|
||||
if (signalStore == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SessionBuilder sessionBuilder =
|
||||
SessionBuilder.fromSignalStore(signalStore, targetAddress);
|
||||
|
||||
ECPublicKey? tempPrePublicKey;
|
||||
int? tempPreKeyId;
|
||||
if (userData.prekeys.isNotEmpty) {
|
||||
tempPrePublicKey = Curve.decodePoint(
|
||||
DjbECPublicKey(Uint8List.fromList(userData.prekeys.first.prekey))
|
||||
.serialize(),
|
||||
1);
|
||||
tempPreKeyId = userData.prekeys.first.id.toInt();
|
||||
}
|
||||
// Signed pre key calculation
|
||||
int tempSignedPreKeyId = userData.signedPrekeyId.toInt();
|
||||
// Map? tempSignedPreKey = remoteBundle["signedPreKey"];
|
||||
ECPublicKey? tempSignedPreKeyPublic;
|
||||
Uint8List? tempSignedPreKeySignature;
|
||||
// if (tempSignedPreKey != null) {
|
||||
tempSignedPreKeyPublic = Curve.decodePoint(
|
||||
DjbECPublicKey(Uint8List.fromList(userData.signedPrekey)).serialize(), 1);
|
||||
tempSignedPreKeySignature =
|
||||
Uint8List.fromList(userData.signedPrekeySignature);
|
||||
// }
|
||||
// Identity key calculation
|
||||
IdentityKey tempIdentityKey = IdentityKey(Curve.decodePoint(
|
||||
DjbECPublicKey(Uint8List.fromList(userData.publicIdentityKey))
|
||||
.serialize(),
|
||||
1));
|
||||
PreKeyBundle preKeyBundle = PreKeyBundle(
|
||||
userData.userId.toInt(),
|
||||
1,
|
||||
tempPreKeyId,
|
||||
tempPrePublicKey,
|
||||
tempSignedPreKeyId,
|
||||
tempSignedPreKeyPublic,
|
||||
tempSignedPreKeySignature,
|
||||
tempIdentityKey,
|
||||
);
|
||||
|
||||
try {
|
||||
await sessionBuilder.processPreKeyBundle(preKeyBundle);
|
||||
return true;
|
||||
} catch (e) {
|
||||
Logger("signal_helper").shout("Error: $e");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<ConnectSignalProtocolStore?> getSignalStore() async {
|
||||
return await getSignalStoreFromIdentity((await getSignalIdentity())!);
|
||||
}
|
||||
|
||||
Future<SignalIdentity?> getSignalIdentity() async {
|
||||
final storage = getSecureStorage();
|
||||
final signalIdentityJson = await storage.read(key: "signal_identity");
|
||||
if (signalIdentityJson == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return SignalIdentity.fromJson(jsonDecode(signalIdentityJson));
|
||||
}
|
||||
|
||||
Future<ConnectSignalProtocolStore> getSignalStoreFromIdentity(
|
||||
SignalIdentity signalIdentity) async {
|
||||
final IdentityKeyPair identityKeyPair =
|
||||
IdentityKeyPair.fromSerialized(signalIdentity.identityKeyPairU8List);
|
||||
|
||||
return ConnectSignalProtocolStore(
|
||||
identityKeyPair, signalIdentity.registrationId.toInt());
|
||||
}
|
||||
|
||||
Future<List<PreKeyRecord>> getPreKeys() 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 createIfNotExistsSignalIdentity() async {
|
||||
final storage = getSecureStorage();
|
||||
|
||||
final signalIdentity = await storage.read(key: "signal_identity");
|
||||
if (signalIdentity != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final identityKeyPair = generateIdentityKeyPair();
|
||||
final registrationId = generateRegistrationId(true);
|
||||
|
||||
ConnectSignalProtocolStore signalStore =
|
||||
ConnectSignalProtocolStore(identityKeyPair, registrationId);
|
||||
|
||||
final signedPreKey = generateSignedPreKey(identityKeyPair, defaultDeviceId);
|
||||
|
||||
await signalStore.signedPreKeyStore
|
||||
.storeSignedPreKey(signedPreKey.id, signedPreKey);
|
||||
|
||||
final storedSignalIdentity = SignalIdentity(
|
||||
identityKeyPairU8List: identityKeyPair.serialize(),
|
||||
registrationId: Int64(registrationId));
|
||||
|
||||
await storage.write(
|
||||
key: "signal_identity", value: jsonEncode(storedSignalIdentity));
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import 'dart:convert';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:twonly/main.dart';
|
||||
import 'package:twonly/src/model/user_data_json.dart';
|
||||
import 'package:twonly/src/model/json/user_data.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
|
||||
Future<bool> isUserCreated() async {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:twonly/src/model/user_data_json.dart';
|
||||
import 'package:twonly/src/model/json/user_data.dart';
|
||||
import 'package:restart_app/restart_app.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:twonly/src/settings/settings_controller.dart';
|
||||
|
|
|
|||
Loading…
Reference in a new issue