From 2eb9fd2f001623f66943fb77065db996fbf95c2f Mon Sep 17 00:00:00 2001 From: otsmr Date: Fri, 30 May 2025 17:50:26 +0200 Subject: [PATCH] split signal functions into multiple files --- lib/src/services/api.service.dart | 13 +- lib/src/services/api/messages.dart | 5 +- lib/src/services/api/server_messages.dart | 8 +- .../services/signal/encryption.signal.dart | 64 +++++ lib/src/services/signal/identity.signal.dart | 62 +++++ lib/src/services/signal/session.signal.dart | 92 +++++++ lib/src/services/signal/utils.signal.dart | 29 +++ lib/src/utils/signal.dart | 229 ------------------ lib/src/views/chats/add_new_user.view.dart | 2 +- .../views/contact/contact_verify.view.dart | 2 +- lib/src/views/register.view.dart | 2 +- 11 files changed, 262 insertions(+), 246 deletions(-) create mode 100644 lib/src/services/signal/encryption.signal.dart create mode 100644 lib/src/services/signal/identity.signal.dart create mode 100644 lib/src/services/signal/session.signal.dart create mode 100644 lib/src/services/signal/utils.signal.dart delete mode 100644 lib/src/utils/signal.dart diff --git a/lib/src/services/api.service.dart b/lib/src/services/api.service.dart index 4c1d94b..ec18240 100644 --- a/lib/src/services/api.service.dart +++ b/lib/src/services/api.service.dart @@ -21,14 +21,14 @@ import 'package:twonly/src/services/api/utils.dart'; import 'package:twonly/src/services/api/media_received.dart'; import 'package:twonly/src/services/api/media_send.dart'; import 'package:twonly/src/services/api/server_messages.dart'; +import 'package:twonly/src/services/signal/identity.signal.dart'; +import 'package:twonly/src/services/signal/utils.signal.dart'; import 'package:twonly/src/utils/hive.dart'; import 'package:twonly/src/services/fcm.service.dart'; import 'package:twonly/src/services/flame.service.dart'; import 'package:twonly/src/utils/log.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'; @@ -306,7 +306,7 @@ class ApiService { Future authenticate() async { if (isAuthenticated) return; - if (await SignalHelper.getSignalIdentity() == null) { + if (await getSignalIdentity() == null) { return; } @@ -329,7 +329,7 @@ class ApiService { final challenge = result.value.authchallenge; - final privKey = await SignalHelper.getPrivateKey(); + final privKey = await getSignalPrivateIdentityKey(); if (privKey == null) return; final random = getRandomUint8List(32); final signature = sign(privKey.serialize(), challenge, random); @@ -358,13 +358,12 @@ class ApiService { } Future register(String username, String? inviteCode) async { - final signalIdentity = await SignalHelper.getSignalIdentity(); + final signalIdentity = await getSignalIdentity(); if (signalIdentity == null) { return Result.error(ErrorCode.InternalError); } - final signalStore = - await SignalHelper.getSignalStoreFromIdentity(signalIdentity); + final signalStore = await getSignalStoreFromIdentity(signalIdentity); final signedPreKey = (await signalStore.loadSignedPreKeys())[0]; diff --git a/lib/src/services/api/messages.dart b/lib/src/services/api/messages.dart index 7fa2b3f..872050b 100644 --- a/lib/src/services/api/messages.dart +++ b/lib/src/services/api/messages.dart @@ -10,10 +10,9 @@ import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/model/json/message.dart'; import 'package:twonly/src/model/json/userdata.dart'; import 'package:twonly/src/services/api/utils.dart'; +import 'package:twonly/src/services/signal/encryption.signal.dart'; import 'package:twonly/src/utils/hive.dart'; import 'package:twonly/src/services/notification.service.dart'; -// ignore: library_prefixes -import 'package:twonly/src/utils/signal.dart' as SignalHelper; import 'package:twonly/src/utils/storage.dart'; final lockSendingMessages = Mutex(); @@ -138,7 +137,7 @@ Future<(String, RetransmitMessage)?> encryptMessage( {PushKind? pushKind}) async { return await lockSendingMessages .protect<(String, RetransmitMessage)?>(() async { - Uint8List? bytes = await SignalHelper.encryptMessage(msg, userId); + Uint8List? bytes = await signalEncryptMessage(userId, msg); if (bytes == null) { Logger("api.dart").shout("Error encryption message!"); diff --git a/lib/src/services/api/server_messages.dart b/lib/src/services/api/server_messages.dart index 4123e00..ebfba91 100644 --- a/lib/src/services/api/server_messages.dart +++ b/lib/src/services/api/server_messages.dart @@ -18,9 +18,9 @@ import 'package:twonly/src/services/api/messages.dart'; import 'package:twonly/src/services/api/utils.dart'; import 'package:twonly/src/services/api/media_received.dart'; import 'package:twonly/src/services/notification.service.dart'; +import 'package:twonly/src/services/signal/encryption.signal.dart'; +import 'package:twonly/src/services/signal/utils.signal.dart'; import 'package:twonly/src/utils/misc.dart'; -// ignore: library_prefixes -import 'package:twonly/src/utils/signal.dart' as SignalHelper; final lockHandleServerMessage = Mutex(); @@ -53,7 +53,7 @@ Future handleServerMessage(server.ServerToClient msg) async { } Future handleNewMessage(int fromUserId, Uint8List body) async { - MessageJson? message = await SignalHelper.getDecryptedText(fromUserId, body); + MessageJson? message = await signalDecryptMessage(fromUserId, body); if (message == null) { Logger("server_messages") .info("Got invalid cipher text from $fromUserId. Deleting it."); @@ -264,7 +264,7 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { } Future handleRequestNewPreKey() async { - List localPreKeys = await SignalHelper.getPreKeys(); + List localPreKeys = await signalGetPreKeys(); List prekeysList = []; for (int i = 0; i < localPreKeys.length; i++) { diff --git a/lib/src/services/signal/encryption.signal.dart b/lib/src/services/signal/encryption.signal.dart new file mode 100644 index 0000000..5ad072e --- /dev/null +++ b/lib/src/services/signal/encryption.signal.dart @@ -0,0 +1,64 @@ +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; +import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; +import 'package:logging/logging.dart'; +import 'package:twonly/src/model/json/message.dart'; +import 'package:twonly/src/database/signal/connect_signal_protocol_store.dart'; +import 'package:twonly/src/services/signal/utils.signal.dart'; +import 'package:twonly/src/utils/misc.dart'; + +Future signalEncryptMessage(int target, MessageJson msg) async { + try { + ConnectSignalProtocolStore signalStore = (await getSignalStore())!; + + SessionCipher session = SessionCipher.fromStore( + signalStore, SignalProtocolAddress(target.toString(), defaultDeviceId)); + + final ciphertext = await session.encrypt( + Uint8List.fromList(gzip.encode(utf8.encode(jsonEncode(msg.toJson()))))); + + var b = BytesBuilder(); + b.add(ciphertext.serialize()); + b.add(intToBytes(ciphertext.getType())); + + return b.takeBytes(); + } catch (e) { + Logger("utils/signal").shout(e.toString()); + return null; + } +} + +Future signalDecryptMessage(int source, Uint8List msg) async { + try { + ConnectSignalProtocolStore signalStore = (await getSignalStore())!; + + SessionCipher session = SessionCipher.fromStore( + signalStore, SignalProtocolAddress(source.toString(), defaultDeviceId)); + + List? msgs = removeLastXBytes(msg, 4); + if (msgs == null) { + Logger("utils/signal").shout("Message requires at least 4 bytes."); + return null; + } + Uint8List body = msgs[0]; + int type = bytesToInt(msgs[1]); + Uint8List plaintext; + if (type == CiphertextMessage.prekeyType) { + PreKeySignalMessage pre = PreKeySignalMessage(body); + plaintext = await session.decrypt(pre); + } else if (type == CiphertextMessage.whisperType) { + SignalMessage signalMsg = SignalMessage.fromSerialized(body); + plaintext = await session.decryptFromSignal(signalMsg); + } else { + Logger("utils/signal").shout("Type not known: $type"); + return null; + } + MessageJson dectext = + MessageJson.fromJson(jsonDecode(utf8.decode(gzip.decode(plaintext)))); + return dectext; + } catch (e) { + Logger("utils/signal").shout(e.toString()); + return null; + } +} diff --git a/lib/src/services/signal/identity.signal.dart b/lib/src/services/signal/identity.signal.dart new file mode 100644 index 0000000..f7c1eca --- /dev/null +++ b/lib/src/services/signal/identity.signal.dart @@ -0,0 +1,62 @@ +import 'dart:convert'; +import 'package:flutter_secure_storage/flutter_secure_storage.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/database/signal/connect_signal_protocol_store.dart'; + +const int defaultDeviceId = 1; + +Future getSignalPrivateIdentityKey() async { + final signalIdentity = await getSignalIdentity(); + if (signalIdentity == null) { + return null; + } + + final IdentityKeyPair identityKeyPair = + IdentityKeyPair.fromSerialized(signalIdentity.identityKeyPairU8List); + + return identityKeyPair.getPrivateKey(); +} + +Future getSignalIdentity() async { + try { + final storage = FlutterSecureStorage(); + final signalIdentityJson = await storage.read(key: "signal_identity"); + if (signalIdentityJson == null) { + return null; + } + return SignalIdentity.fromJson(jsonDecode(signalIdentityJson)); + } catch (e) { + Logger("signal.dart/getSignalIdentity").shout(e); + return null; + } +} + +Future createIfNotExistsSignalIdentity() async { + final storage = FlutterSecureStorage(); + + 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: registrationId, + ); + + await storage.write( + key: "signal_identity", value: jsonEncode(storedSignalIdentity)); +} diff --git a/lib/src/services/signal/session.signal.dart b/lib/src/services/signal/session.signal.dart new file mode 100644 index 0000000..bd0c863 --- /dev/null +++ b/lib/src/services/signal/session.signal.dart @@ -0,0 +1,92 @@ +import 'dart:typed_data'; +import 'package:libsignal_protocol_dart/libsignal_protocol_dart.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/database/signal/connect_signal_protocol_store.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 createNewSignalSession(Response_UserData userData) async { + final int userId = userData.userId.toInt(); + + 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(); + } + + int tempSignedPreKeyId = userData.signedPrekeyId.toInt(); + + ECPublicKey? tempSignedPreKeyPublic = Curve.decodePoint( + DjbECPublicKey(Uint8List.fromList(userData.signedPrekey)).serialize(), 1); + + Uint8List? tempSignedPreKeySignature = + Uint8List.fromList(userData.signedPrekeySignature); + + 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) { + Log.error("could not process pre key bundle: $e"); + return false; + } +} + +Future generateSessionFingerPrint(int target) async { + ConnectSignalProtocolStore? signalStore = await getSignalStore(); + UserData? user = await getUser(); + if (signalStore == null || user == null) return null; + try { + IdentityKey? targetIdentity = await signalStore + .getIdentity(SignalProtocolAddress(target.toString(), defaultDeviceId)); + if (targetIdentity != null) { + final generator = NumericFingerprintGenerator(5200); + final localFingerprint = generator.createFor( + 1, + Uint8List.fromList([user.userId.toInt()]), + (await signalStore.getIdentityKeyPair()).getPublicKey(), + Uint8List.fromList([target.toInt()]), + targetIdentity, + ); + + return localFingerprint; + } + return null; + } catch (e) { + return null; + } +} diff --git a/lib/src/services/signal/utils.signal.dart b/lib/src/services/signal/utils.signal.dart new file mode 100644 index 0000000..6c83c1a --- /dev/null +++ b/lib/src/services/signal/utils.signal.dart @@ -0,0 +1,29 @@ +import 'package:libsignal_protocol_dart/libsignal_protocol_dart.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/services/signal/identity.signal.dart'; + +const int defaultDeviceId = 1; + +Future getSignalStore() async { + return await getSignalStoreFromIdentity((await getSignalIdentity())!); +} + +Future getSignalStoreFromIdentity( + SignalIdentity signalIdentity) async { + final IdentityKeyPair identityKeyPair = + IdentityKeyPair.fromSerialized(signalIdentity.identityKeyPairU8List); + + return ConnectSignalProtocolStore( + identityKeyPair, signalIdentity.registrationId.toInt()); +} + +Future> 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; +} diff --git a/lib/src/utils/signal.dart b/lib/src/utils/signal.dart deleted file mode 100644 index b2cca2d..0000000 --- a/lib/src/utils/signal.dart +++ /dev/null @@ -1,229 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'dart:typed_data'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; -import 'package:logging/logging.dart'; -import 'package:twonly/src/model/json/message.dart'; -import 'package:twonly/src/model/json/signal_identity.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/database/signal/connect_signal_protocol_store.dart'; -import 'package:twonly/src/utils/misc.dart'; -import 'package:twonly/src/utils/storage.dart'; - -const int defaultDeviceId = 1; - -Future getPrivateKey() async { - final signalIdentity = await getSignalIdentity(); - if (signalIdentity == null) { - return null; - } - - final IdentityKeyPair identityKeyPair = - IdentityKeyPair.fromSerialized(signalIdentity.identityKeyPairU8List); - - return identityKeyPair.getPrivateKey(); -} - -Future addNewContact(Response_UserData userData) async { - final int userId = userData.userId.toInt(); - - 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(); - } - - int tempSignedPreKeyId = userData.signedPrekeyId.toInt(); - - ECPublicKey? tempSignedPreKeyPublic = Curve.decodePoint( - DjbECPublicKey(Uint8List.fromList(userData.signedPrekey)).serialize(), 1); - - Uint8List? tempSignedPreKeySignature = - Uint8List.fromList(userData.signedPrekeySignature); - - 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 getSignalStore() async { - return await getSignalStoreFromIdentity((await getSignalIdentity())!); -} - -Future getSignalIdentity() async { - try { - final storage = FlutterSecureStorage(); - final signalIdentityJson = await storage.read(key: "signal_identity"); - if (signalIdentityJson == null) { - return null; - } - return SignalIdentity.fromJson(jsonDecode(signalIdentityJson)); - } catch (e) { - Logger("signal.dart/getSignalIdentity").shout(e); - return null; - } -} - -Future getSignalStoreFromIdentity( - SignalIdentity signalIdentity) async { - final IdentityKeyPair identityKeyPair = - IdentityKeyPair.fromSerialized(signalIdentity.identityKeyPairU8List); - - return ConnectSignalProtocolStore( - identityKeyPair, signalIdentity.registrationId.toInt()); -} - -Future> 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 = FlutterSecureStorage(); - - 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: registrationId, - ); - - await storage.write( - key: "signal_identity", value: jsonEncode(storedSignalIdentity)); -} - -Future generateSessionFingerPrint(int target) async { - ConnectSignalProtocolStore? signalStore = await getSignalStore(); - UserData? user = await getUser(); - if (signalStore == null || user == null) return null; - try { - IdentityKey? targetIdentity = await signalStore - .getIdentity(SignalProtocolAddress(target.toString(), defaultDeviceId)); - if (targetIdentity != null) { - final generator = NumericFingerprintGenerator(5200); - final localFingerprint = generator.createFor( - 1, - Uint8List.fromList([user.userId.toInt()]), - (await signalStore.getIdentityKeyPair()).getPublicKey(), - Uint8List.fromList([target.toInt()]), - targetIdentity, - ); - - return localFingerprint; - } - return null; - } catch (e) { - return null; - } -} - -Future encryptMessage(MessageJson msg, int target) async { - try { - ConnectSignalProtocolStore signalStore = (await getSignalStore())!; - - SessionCipher session = SessionCipher.fromStore( - signalStore, SignalProtocolAddress(target.toString(), defaultDeviceId)); - - final ciphertext = await session.encrypt( - Uint8List.fromList(gzip.encode(utf8.encode(jsonEncode(msg.toJson()))))); - - var b = BytesBuilder(); - b.add(ciphertext.serialize()); - b.add(intToBytes(ciphertext.getType())); - - return b.takeBytes(); - } catch (e) { - Logger("utils/signal").shout(e.toString()); - return null; - } -} - -Future getDecryptedText(int source, Uint8List msg) async { - try { - ConnectSignalProtocolStore signalStore = (await getSignalStore())!; - - SessionCipher session = SessionCipher.fromStore( - signalStore, SignalProtocolAddress(source.toString(), defaultDeviceId)); - - List? msgs = removeLastXBytes(msg, 4); - if (msgs == null) { - Logger("utils/signal").shout("Message requires at least 4 bytes."); - return null; - } - Uint8List body = msgs[0]; - int type = bytesToInt(msgs[1]); - Uint8List plaintext; - if (type == CiphertextMessage.prekeyType) { - PreKeySignalMessage pre = PreKeySignalMessage(body); - plaintext = await session.decrypt(pre); - } else if (type == CiphertextMessage.whisperType) { - SignalMessage signalMsg = SignalMessage.fromSerialized(body); - plaintext = await session.decryptFromSignal(signalMsg); - } else { - Logger("utils/signal").shout("Type not known: $type"); - return null; - } - MessageJson dectext = - MessageJson.fromJson(jsonDecode(utf8.decode(gzip.decode(plaintext)))); - return dectext; - } catch (e) { - Logger("utils/signal").shout(e.toString()); - return null; - } -} diff --git a/lib/src/views/chats/add_new_user.view.dart b/lib/src/views/chats/add_new_user.view.dart index 847e598..65e2966 100644 --- a/lib/src/views/chats/add_new_user.view.dart +++ b/lib/src/views/chats/add_new_user.view.dart @@ -17,7 +17,7 @@ import 'package:twonly/src/views/components/initialsavatar.dart'; import 'package:twonly/src/model/json/message.dart'; import 'package:twonly/src/services/api/messages.dart'; // ignore: library_prefixes -import 'package:twonly/src/utils/signal.dart' as SignalHelper; +import 'package:twonly/src/services/signal/utils.signal.dart' as SignalHelper; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/settings/subscription/subscription_view.dart'; diff --git a/lib/src/views/contact/contact_verify.view.dart b/lib/src/views/contact/contact_verify.view.dart index 6b21745..f3c1e8f 100644 --- a/lib/src/views/contact/contact_verify.view.dart +++ b/lib/src/views/contact/contact_verify.view.dart @@ -9,7 +9,7 @@ import 'package:flutter/material.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/utils/misc.dart'; -import 'package:twonly/src/utils/signal.dart'; +import 'package:twonly/src/services/signal/utils.signal.dart'; import 'package:url_launcher/url_launcher.dart'; class ContactVerifyView extends StatefulWidget { diff --git a/lib/src/views/register.view.dart b/lib/src/views/register.view.dart index 58b5d88..bb8dad3 100644 --- a/lib/src/views/register.view.dart +++ b/lib/src/views/register.view.dart @@ -5,10 +5,10 @@ import 'package:logging/logging.dart'; import 'package:twonly/globals.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:twonly/src/services/signal/identity.signal.dart'; import 'package:twonly/src/views/components/alert_dialog.dart'; import 'package:twonly/src/model/json/userdata.dart'; import 'package:twonly/src/utils/misc.dart'; -import 'package:twonly/src/utils/signal.dart'; class RegisterView extends StatefulWidget { const RegisterView({super.key, required this.callbackOnSuccess});