diff --git a/flutter_rust_bridge.yaml b/flutter_rust_bridge.yaml index bbdc703..17b5a8f 100644 --- a/flutter_rust_bridge.yaml +++ b/flutter_rust_bridge.yaml @@ -1,3 +1,3 @@ -rust_input: crate::twonly -rust_root: rust/ +rust_input: crate::bridge +rust_root: rust/core dart_output: lib/core \ No newline at end of file diff --git a/lib/core/bridge.dart b/lib/core/bridge.dart new file mode 100644 index 0000000..1e4d9ec --- /dev/null +++ b/lib/core/bridge.dart @@ -0,0 +1,76 @@ +// This file is automatically generated, so please do not edit it. +// @generated by `flutter_rust_bridge`@ 2.12.0. + +// ignore_for_file: invalid_use_of_internal_member + +import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; + +import 'database/contact.dart'; +import 'frb_generated.dart'; + +// These functions are ignored because they are not marked as `pub`: `get_instance` +// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `Twonly` + +Future initializeTwonly({required TwonlyConfig config}) => + RustLib.instance.api.crateBridgeInitializeTwonly(config: config); + +Future> getAllContacts() => + RustLib.instance.api.crateBridgeGetAllContacts(); + +Future loadPromotions() => + RustLib.instance.api.crateBridgeLoadPromotions(); + +class OtherPromotion { + const OtherPromotion({ + required this.promotionId, + required this.publicId, + required this.fromContactId, + required this.threshold, + required this.announcementShare, + this.publicKeyVerifiedTimestamp, + }); + final int promotionId; + final BigInt publicId; + final PlatformInt64 fromContactId; + final int threshold; + final Uint8List announcementShare; + final PlatformInt64? publicKeyVerifiedTimestamp; + + @override + int get hashCode => + promotionId.hashCode ^ + publicId.hashCode ^ + fromContactId.hashCode ^ + threshold.hashCode ^ + announcementShare.hashCode ^ + publicKeyVerifiedTimestamp.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is OtherPromotion && + runtimeType == other.runtimeType && + promotionId == other.promotionId && + publicId == other.publicId && + fromContactId == other.fromContactId && + threshold == other.threshold && + announcementShare == other.announcementShare && + publicKeyVerifiedTimestamp == other.publicKeyVerifiedTimestamp; +} + +class TwonlyConfig { + const TwonlyConfig({ + required this.databasePath, + }); + final String databasePath; + + @override + int get hashCode => databasePath.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is TwonlyConfig && + runtimeType == other.runtimeType && + databasePath == other.databasePath; +} diff --git a/lib/core/twonly/database/contact.dart b/lib/core/database/contact.dart similarity index 60% rename from lib/core/twonly/database/contact.dart rename to lib/core/database/contact.dart index aa7b3f4..42799c8 100644 --- a/lib/core/twonly/database/contact.dart +++ b/lib/core/database/contact.dart @@ -5,11 +5,7 @@ import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; -import '../../frb_generated.dart'; - -// These functions are ignored because they are not marked as `pub`: `get_all_contacts` -// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `ContactRow` -// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `fmt`, `from_row`, `from` +import '../frb_generated.dart'; class Contact { const Contact({ diff --git a/lib/core/frb_generated.dart b/lib/core/frb_generated.dart index 0595861..e6257b4 100644 --- a/lib/core/frb_generated.dart +++ b/lib/core/frb_generated.dart @@ -8,11 +8,11 @@ import 'dart:convert'; import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; +import 'bridge.dart'; +import 'database/contact.dart'; import 'frb_generated.dart'; import 'frb_generated.io.dart' if (dart.library.js_interop) 'frb_generated.web.dart'; -import 'twonly.dart'; -import 'twonly/database/contact.dart'; /// Main entrypoint of the Rust API class RustLib extends BaseEntrypoint { @@ -70,20 +70,22 @@ class RustLib extends BaseEntrypoint { String get codegenVersion => '2.12.0'; @override - int get rustContentHash => 741438464; + int get rustContentHash => 776002844; static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig( stem: 'rust_lib_twonly', - ioDirectory: 'rust/target/release/', + ioDirectory: 'rust/core/target/release/', webPrefix: 'pkg/', ); } abstract class RustLibApi extends BaseApi { - Future> crateTwonlyGetAllContacts(); + Future> crateBridgeGetAllContacts(); - Future crateTwonlyInitializeTwonly({required TwonlyConfig config}); + Future crateBridgeInitializeTwonly({required TwonlyConfig config}); + + Future crateBridgeLoadPromotions(); } class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { @@ -95,7 +97,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { }); @override - Future> crateTwonlyGetAllContacts() { + Future> crateBridgeGetAllContacts() { return handler.executeNormal( NormalTask( callFfi: (port_) { @@ -111,20 +113,20 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { decodeSuccessData: sse_decode_list_contact, decodeErrorData: sse_decode_AnyhowException, ), - constMeta: kCrateTwonlyGetAllContactsConstMeta, + constMeta: kCrateBridgeGetAllContactsConstMeta, argValues: [], apiImpl: this, ), ); } - TaskConstMeta get kCrateTwonlyGetAllContactsConstMeta => const TaskConstMeta( + TaskConstMeta get kCrateBridgeGetAllContactsConstMeta => const TaskConstMeta( debugName: 'get_all_contacts', argNames: [], ); @override - Future crateTwonlyInitializeTwonly({required TwonlyConfig config}) { + Future crateBridgeInitializeTwonly({required TwonlyConfig config}) { return handler.executeNormal( NormalTask( callFfi: (port_) { @@ -141,19 +143,48 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { decodeSuccessData: sse_decode_unit, decodeErrorData: sse_decode_AnyhowException, ), - constMeta: kCrateTwonlyInitializeTwonlyConstMeta, + constMeta: kCrateBridgeInitializeTwonlyConstMeta, argValues: [config], apiImpl: this, ), ); } - TaskConstMeta get kCrateTwonlyInitializeTwonlyConstMeta => + TaskConstMeta get kCrateBridgeInitializeTwonlyConstMeta => const TaskConstMeta( debugName: 'initialize_twonly', argNames: ['config'], ); + @override + Future crateBridgeLoadPromotions() { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 3, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_other_promotion, + decodeErrorData: null, + ), + constMeta: kCrateBridgeLoadPromotionsConstMeta, + argValues: [], + apiImpl: this, + ), + ); + } + + TaskConstMeta get kCrateBridgeLoadPromotionsConstMeta => const TaskConstMeta( + debugName: 'load_promotions', + argNames: [], + ); + @protected AnyhowException dco_decode_AnyhowException(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -166,6 +197,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return raw as String; } + @protected + PlatformInt64 dco_decode_box_autoadd_i_64(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return dco_decode_i_64(raw); + } + @protected TwonlyConfig dco_decode_box_autoadd_twonly_config(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -202,6 +239,28 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return raw as Uint8List; } + @protected + PlatformInt64? dco_decode_opt_box_autoadd_i_64(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return raw == null ? null : dco_decode_box_autoadd_i_64(raw); + } + + @protected + OtherPromotion dco_decode_other_promotion(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + final arr = raw as List; + if (arr.length != 6) + throw Exception('unexpected arr length: expect 6 but see ${arr.length}'); + return OtherPromotion( + promotionId: dco_decode_u_32(arr[0]), + publicId: dco_decode_u_64(arr[1]), + fromContactId: dco_decode_i_64(arr[2]), + threshold: dco_decode_u_8(arr[3]), + announcementShare: dco_decode_list_prim_u_8_strict(arr[4]), + publicKeyVerifiedTimestamp: dco_decode_opt_box_autoadd_i_64(arr[5]), + ); + } + @protected TwonlyConfig dco_decode_twonly_config(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -213,6 +272,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + int dco_decode_u_32(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return raw as int; + } + + @protected + BigInt dco_decode_u_64(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return dcoDecodeU64(raw); + } + @protected int dco_decode_u_8(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -239,6 +310,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return utf8.decoder.convert(inner); } + @protected + PlatformInt64 sse_decode_box_autoadd_i_64(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return sse_decode_i_64(deserializer); + } + @protected TwonlyConfig sse_decode_box_autoadd_twonly_config( SseDeserializer deserializer, @@ -280,6 +357,38 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return deserializer.buffer.getUint8List(len_); } + @protected + PlatformInt64? sse_decode_opt_box_autoadd_i_64(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + + if (sse_decode_bool(deserializer)) { + return sse_decode_box_autoadd_i_64(deserializer); + } else { + return null; + } + } + + @protected + OtherPromotion sse_decode_other_promotion(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + final var_promotionId = sse_decode_u_32(deserializer); + final var_publicId = sse_decode_u_64(deserializer); + final var_fromContactId = sse_decode_i_64(deserializer); + final var_threshold = sse_decode_u_8(deserializer); + final var_announcementShare = sse_decode_list_prim_u_8_strict(deserializer); + final var_publicKeyVerifiedTimestamp = sse_decode_opt_box_autoadd_i_64( + deserializer, + ); + return OtherPromotion( + promotionId: var_promotionId, + publicId: var_publicId, + fromContactId: var_fromContactId, + threshold: var_threshold, + announcementShare: var_announcementShare, + publicKeyVerifiedTimestamp: var_publicKeyVerifiedTimestamp, + ); + } + @protected TwonlyConfig sse_decode_twonly_config(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -287,6 +396,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return TwonlyConfig(databasePath: var_databasePath); } + @protected + int sse_decode_u_32(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return deserializer.buffer.getUint32(); + } + + @protected + BigInt sse_decode_u_64(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return deserializer.buffer.getBigUint64(); + } + @protected int sse_decode_u_8(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -325,6 +446,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer); } + @protected + void sse_encode_box_autoadd_i_64( + PlatformInt64 self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_i_64(self, serializer); + } + @protected void sse_encode_box_autoadd_twonly_config( TwonlyConfig self, @@ -366,12 +496,54 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer.buffer.putUint8List(self); } + @protected + void sse_encode_opt_box_autoadd_i_64( + PlatformInt64? self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + + sse_encode_bool(self != null, serializer); + if (self != null) { + sse_encode_box_autoadd_i_64(self, serializer); + } + } + + @protected + void sse_encode_other_promotion( + OtherPromotion self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_u_32(self.promotionId, serializer); + sse_encode_u_64(self.publicId, serializer); + sse_encode_i_64(self.fromContactId, serializer); + sse_encode_u_8(self.threshold, serializer); + sse_encode_list_prim_u_8_strict(self.announcementShare, serializer); + sse_encode_opt_box_autoadd_i_64( + self.publicKeyVerifiedTimestamp, + serializer, + ); + } + @protected void sse_encode_twonly_config(TwonlyConfig self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs sse_encode_String(self.databasePath, serializer); } + @protected + void sse_encode_u_32(int self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + serializer.buffer.putUint32(self); + } + + @protected + void sse_encode_u_64(BigInt self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + serializer.buffer.putBigUint64(self); + } + @protected void sse_encode_u_8(int self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs diff --git a/lib/core/frb_generated.io.dart b/lib/core/frb_generated.io.dart index 93c3b48..910683b 100644 --- a/lib/core/frb_generated.io.dart +++ b/lib/core/frb_generated.io.dart @@ -9,9 +9,9 @@ import 'dart:ffi' as ffi; import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_io.dart'; +import 'bridge.dart'; +import 'database/contact.dart'; import 'frb_generated.dart'; -import 'twonly.dart'; -import 'twonly/database/contact.dart'; abstract class RustLibApiImplPlatform extends BaseApiImpl { RustLibApiImplPlatform({ @@ -27,6 +27,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected String dco_decode_String(dynamic raw); + @protected + PlatformInt64 dco_decode_box_autoadd_i_64(dynamic raw); + @protected TwonlyConfig dco_decode_box_autoadd_twonly_config(dynamic raw); @@ -42,9 +45,21 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected Uint8List dco_decode_list_prim_u_8_strict(dynamic raw); + @protected + PlatformInt64? dco_decode_opt_box_autoadd_i_64(dynamic raw); + + @protected + OtherPromotion dco_decode_other_promotion(dynamic raw); + @protected TwonlyConfig dco_decode_twonly_config(dynamic raw); + @protected + int dco_decode_u_32(dynamic raw); + + @protected + BigInt dco_decode_u_64(dynamic raw); + @protected int dco_decode_u_8(dynamic raw); @@ -57,6 +72,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected String sse_decode_String(SseDeserializer deserializer); + @protected + PlatformInt64 sse_decode_box_autoadd_i_64(SseDeserializer deserializer); + @protected TwonlyConfig sse_decode_box_autoadd_twonly_config( SseDeserializer deserializer, @@ -74,9 +92,21 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer); + @protected + PlatformInt64? sse_decode_opt_box_autoadd_i_64(SseDeserializer deserializer); + + @protected + OtherPromotion sse_decode_other_promotion(SseDeserializer deserializer); + @protected TwonlyConfig sse_decode_twonly_config(SseDeserializer deserializer); + @protected + int sse_decode_u_32(SseDeserializer deserializer); + + @protected + BigInt sse_decode_u_64(SseDeserializer deserializer); + @protected int sse_decode_u_8(SseDeserializer deserializer); @@ -98,6 +128,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_String(String self, SseSerializer serializer); + @protected + void sse_encode_box_autoadd_i_64( + PlatformInt64 self, + SseSerializer serializer, + ); + @protected void sse_encode_box_autoadd_twonly_config( TwonlyConfig self, @@ -119,9 +155,27 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void sse_encode_opt_box_autoadd_i_64( + PlatformInt64? self, + SseSerializer serializer, + ); + + @protected + void sse_encode_other_promotion( + OtherPromotion self, + SseSerializer serializer, + ); + @protected void sse_encode_twonly_config(TwonlyConfig self, SseSerializer serializer); + @protected + void sse_encode_u_32(int self, SseSerializer serializer); + + @protected + void sse_encode_u_64(BigInt self, SseSerializer serializer); + @protected void sse_encode_u_8(int self, SseSerializer serializer); diff --git a/lib/core/frb_generated.web.dart b/lib/core/frb_generated.web.dart index e737ff4..d45c031 100644 --- a/lib/core/frb_generated.web.dart +++ b/lib/core/frb_generated.web.dart @@ -10,9 +10,9 @@ import 'dart:convert'; import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_web.dart'; +import 'bridge.dart'; +import 'database/contact.dart'; import 'frb_generated.dart'; -import 'twonly.dart'; -import 'twonly/database/contact.dart'; abstract class RustLibApiImplPlatform extends BaseApiImpl { RustLibApiImplPlatform({ @@ -28,6 +28,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected String dco_decode_String(dynamic raw); + @protected + PlatformInt64 dco_decode_box_autoadd_i_64(dynamic raw); + @protected TwonlyConfig dco_decode_box_autoadd_twonly_config(dynamic raw); @@ -43,9 +46,21 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected Uint8List dco_decode_list_prim_u_8_strict(dynamic raw); + @protected + PlatformInt64? dco_decode_opt_box_autoadd_i_64(dynamic raw); + + @protected + OtherPromotion dco_decode_other_promotion(dynamic raw); + @protected TwonlyConfig dco_decode_twonly_config(dynamic raw); + @protected + int dco_decode_u_32(dynamic raw); + + @protected + BigInt dco_decode_u_64(dynamic raw); + @protected int dco_decode_u_8(dynamic raw); @@ -58,6 +73,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected String sse_decode_String(SseDeserializer deserializer); + @protected + PlatformInt64 sse_decode_box_autoadd_i_64(SseDeserializer deserializer); + @protected TwonlyConfig sse_decode_box_autoadd_twonly_config( SseDeserializer deserializer, @@ -75,9 +93,21 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer); + @protected + PlatformInt64? sse_decode_opt_box_autoadd_i_64(SseDeserializer deserializer); + + @protected + OtherPromotion sse_decode_other_promotion(SseDeserializer deserializer); + @protected TwonlyConfig sse_decode_twonly_config(SseDeserializer deserializer); + @protected + int sse_decode_u_32(SseDeserializer deserializer); + + @protected + BigInt sse_decode_u_64(SseDeserializer deserializer); + @protected int sse_decode_u_8(SseDeserializer deserializer); @@ -99,6 +129,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_String(String self, SseSerializer serializer); + @protected + void sse_encode_box_autoadd_i_64( + PlatformInt64 self, + SseSerializer serializer, + ); + @protected void sse_encode_box_autoadd_twonly_config( TwonlyConfig self, @@ -120,9 +156,27 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void sse_encode_opt_box_autoadd_i_64( + PlatformInt64? self, + SseSerializer serializer, + ); + + @protected + void sse_encode_other_promotion( + OtherPromotion self, + SseSerializer serializer, + ); + @protected void sse_encode_twonly_config(TwonlyConfig self, SseSerializer serializer); + @protected + void sse_encode_u_32(int self, SseSerializer serializer); + + @protected + void sse_encode_u_64(BigInt self, SseSerializer serializer); + @protected void sse_encode_u_8(int self, SseSerializer serializer); diff --git a/lib/core/twonly.dart b/lib/core/twonly.dart deleted file mode 100644 index 6548448..0000000 --- a/lib/core/twonly.dart +++ /dev/null @@ -1,35 +0,0 @@ -// This file is automatically generated, so please do not edit it. -// @generated by `flutter_rust_bridge`@ 2.12.0. - -// ignore_for_file: invalid_use_of_internal_member, unused_import - -import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; - -import 'frb_generated.dart'; -import 'twonly/database/contact.dart'; - -// These functions are ignored because they are not marked as `pub`: `get_instance` -// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `Twonly` - -Future initializeTwonly({required TwonlyConfig config}) => - RustLib.instance.api.crateTwonlyInitializeTwonly(config: config); - -Future> getAllContacts() => - RustLib.instance.api.crateTwonlyGetAllContacts(); - -class TwonlyConfig { - const TwonlyConfig({ - required this.databasePath, - }); - final String databasePath; - - @override - int get hashCode => databasePath.hashCode; - - @override - bool operator ==(Object other) => - identical(this, other) || - other is TwonlyConfig && - runtimeType == other.runtimeType && - databasePath == other.databasePath; -} diff --git a/lib/core/twonly/database.dart b/lib/core/twonly/database.dart deleted file mode 100644 index 98b7e34..0000000 --- a/lib/core/twonly/database.dart +++ /dev/null @@ -1,20 +0,0 @@ -// This file is automatically generated, so please do not edit it. -// @generated by `flutter_rust_bridge`@ 2.12.0. - -// ignore_for_file: unused_import - -import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; - -import '../frb_generated.dart'; - -// These functions are ignored because they are not marked as `pub`: `new` - -// Rust type: RustOpaqueMoi> -abstract class Database implements RustOpaqueInterface { - SqlitePool get pool; - - set pool(SqlitePool pool); -} - -// Rust type: RustOpaqueMoi> -abstract class SqlitePool implements RustOpaqueInterface {} diff --git a/lib/main.dart b/lib/main.dart index 657ebab..0236f63 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,8 +7,8 @@ import 'package:path_provider/path_provider.dart'; import 'package:provider/provider.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:twonly/app.dart'; +import 'package:twonly/core/bridge.dart' as bridge; import 'package:twonly/core/frb_generated.dart'; -import 'package:twonly/core/twonly.dart' as core; import 'package:twonly/globals.dart'; import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/providers/connection.provider.dart'; @@ -37,8 +37,8 @@ void main() async { globalApplicationSupportDirectory = (await getApplicationSupportDirectory()).path; - await core.initializeTwonly( - config: core.TwonlyConfig( + await bridge.initializeTwonly( + config: bridge.TwonlyConfig( databasePath: '$globalApplicationSupportDirectory/twonly.sqlite', ), ); diff --git a/lib/src/database/tables/user_discovery.table.dart b/lib/src/database/tables/user_discovery.table.dart new file mode 100644 index 0000000..68432a5 --- /dev/null +++ b/lib/src/database/tables/user_discovery.table.dart @@ -0,0 +1,48 @@ +import 'package:drift/drift.dart'; +import 'package:twonly/src/database/tables/contacts.table.dart'; + +// contact_versions: HashMap>, +// -> New Column in Contacts + +// config: Option>, + +// announced_users: HashMap)>>, + +// own_promotions: Vec<(UserID, Vec)>, +@DataClassName('UserDiscoveryOwnPromotion') +class UserDiscoveryOwnPromotions extends Table { + IntColumn get versionId => integer().autoIncrement()(); + IntColumn get contactId => integer().references( + Contacts, + #userId, + onDelete: KeyAction.cascade, + )(); + + BlobColumn get promotion => blob()(); +} + +// other_promotions: Vec, +@DataClassName('UserDiscoveryOtherPromotion') +class UserDiscoveryOtherPromotions extends Table { + IntColumn get versionId => integer().autoIncrement()(); + IntColumn get contactId => integer().references( + Contacts, + #userId, + onDelete: KeyAction.cascade, + )(); + + BlobColumn get promotion => blob()(); +} + +// unused_shares: Vec>, +// used_shares: HashMap>, +@DataClassName('UserDiscoveryShare') +class UserDiscoveryShares extends Table { + IntColumn get shareId => integer().autoIncrement()(); + BlobColumn get share => blob()(); + IntColumn get contactId => integer().nullable().references( + Contacts, + #userId, + onDelete: KeyAction.cascade, + )(); +} diff --git a/rust/.gitignore b/rust/.gitignore index dfb400c..c41cc9e 100644 --- a/rust/.gitignore +++ b/rust/.gitignore @@ -1,3 +1 @@ -/target - -tests/tmp_testing.db* \ No newline at end of file +/target \ No newline at end of file diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 07f9c79..918c346 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -4,24 +4,24 @@ version = 4 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -101,23 +101,23 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-link", ] [[package]] @@ -134,9 +134,9 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" dependencies = [ "serde_core", ] @@ -161,6 +161,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + [[package]] name = "build-target" version = "0.4.0" @@ -169,15 +178,15 @@ checksum = "832133bbabbbaa9fbdba793456a2827627a7d2b8fb96032fa1e7666d7895832b" [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" [[package]] name = "byteorder" @@ -203,9 +212,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" @@ -215,7 +224,7 @@ checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" dependencies = [ "cfg-if", "cpufeatures 0.3.0", - "rand_core 0.10.0", + "rand_core 0.10.1", ] [[package]] @@ -229,6 +238,12 @@ dependencies = [ "windows-link", ] +[[package]] +name = "cmov" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" + [[package]] name = "cobs" version = "0.3.0" @@ -263,6 +278,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -325,14 +346,32 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + [[package]] name = "dart-sys" version = "4.1.5" @@ -372,7 +411,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "const-oid", + "const-oid 0.9.6", "pem-rfc7468", "zeroize", ] @@ -383,12 +422,24 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", + "block-buffer 0.10.4", + "const-oid 0.9.6", + "crypto-common 0.1.7", "subtle", ] +[[package]] +name = "digest" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +dependencies = [ + "block-buffer 0.12.0", + "const-oid 0.10.2", + "crypto-common 0.2.1", + "ctutils", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -514,7 +565,7 @@ checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" dependencies = [ "futures-core", "futures-sink", - "spin 0.9.8", + "spin", ] [[package]] @@ -582,9 +633,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.29" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -597,9 +648,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -607,15 +658,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -635,15 +686,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", @@ -652,21 +703,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -676,7 +727,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -710,16 +760,16 @@ dependencies = [ "cfg-if", "libc", "r-efi", - "rand_core 0.10.0", + "rand_core 0.10.1", "wasip2", "wasip3", ] [[package]] name = "gimli" -version = "0.28.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "hash32" @@ -783,7 +833,7 @@ dependencies = [ "hash32", "rustc_version", "serde", - "spin 0.9.8", + "spin", "stable_deref_trait", ] @@ -793,12 +843,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - [[package]] name = "hermit-abi" version = "0.5.2" @@ -817,7 +861,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac", + "hmac 0.12.1", ] [[package]] @@ -826,7 +870,16 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", +] + +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.2", ] [[package]] @@ -844,6 +897,15 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" +[[package]] +name = "hybrid-array" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" +dependencies = [ + "typenum", +] + [[package]] name = "iana-time-zone" version = "0.1.65" @@ -995,7 +1057,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ - "hermit-abi 0.5.2", + "hermit-abi", "libc", "windows-sys 0.61.2", ] @@ -1017,20 +1079,23 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" dependencies = [ + "cfg-if", + "futures-util", + "once_cell", "wasm-bindgen", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.5.2", + "spin", ] [[package]] @@ -1041,9 +1106,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.184" +version = "0.2.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" [[package]] name = "libm" @@ -1076,9 +1141,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.15" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" @@ -1097,9 +1162,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "md-5" @@ -1108,22 +1173,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ "cfg-if", - "digest", + "digest 0.10.7", ] [[package]] name = "memchr" -version = "2.6.4" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -1191,28 +1256,28 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi", "libc", ] [[package]] name = "object" -version = "0.32.1" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oslog" @@ -1282,15 +1347,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs1" @@ -1315,9 +1374,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "plain" @@ -1442,6 +1501,24 @@ dependencies = [ "prost", ] +[[package]] +name = "protocols" +version = "0.1.0" +dependencies = [ + "base64", + "blahaj", + "hmac 0.13.0", + "postcard", + "pretty_env_logger", + "prost", + "prost-build", + "rand 0.10.1", + "serde", + "sha2 0.11.0", + "thiserror", + "tracing", +] + [[package]] name = "quote" version = "1.0.45" @@ -1476,7 +1553,7 @@ checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" dependencies = [ "chacha20", "getrandom 0.4.2", - "rand_core 0.10.0", + "rand_core 0.10.1", ] [[package]] @@ -1500,9 +1577,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] name = "redox_syscall" @@ -1524,9 +1601,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -1536,9 +1613,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -1547,9 +1624,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "rsa" @@ -1557,8 +1634,8 @@ version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ - "const-oid", - "digest", + "const-oid 0.9.6", + "digest 0.10.7", "num-bigint-dig", "num-integer", "num-traits", @@ -1575,14 +1652,11 @@ dependencies = [ name = "rust_lib_twonly" version = "0.1.0" dependencies = [ - "blahaj", "flutter_rust_bridge", - "postcard", "pretty_env_logger", - "prost", "prost-build", + "protocols", "rand 0.10.1", - "serde", "sqlx", "thiserror", "tokio", @@ -1591,9 +1665,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc_version" @@ -1606,17 +1680,23 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.44" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + [[package]] name = "ryu" version = "1.0.23" @@ -1698,7 +1778,7 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", ] [[package]] @@ -1709,7 +1789,18 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.2", ] [[package]] @@ -1734,18 +1825,15 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] [[package]] name = "slab" -version = "0.4.9" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" @@ -1766,12 +1854,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -1830,7 +1912,7 @@ dependencies = [ "percent-encoding", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "thiserror", "tokio", @@ -1867,7 +1949,7 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "sqlx-core", "sqlx-mysql", "sqlx-postgres", @@ -1891,7 +1973,7 @@ dependencies = [ "bytes", "chrono", "crc", - "digest", + "digest 0.10.7", "dotenvy", "either", "futures-channel", @@ -1901,7 +1983,7 @@ dependencies = [ "generic-array", "hex", "hkdf", - "hmac", + "hmac 0.12.1", "itoa", "log", "md-5", @@ -1911,7 +1993,7 @@ dependencies = [ "rsa", "serde", "sha1", - "sha2", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -1939,7 +2021,7 @@ dependencies = [ "futures-util", "hex", "hkdf", - "hmac", + "hmac 0.12.1", "home", "itoa", "log", @@ -1948,7 +2030,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -2029,14 +2111,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ - "cfg-if", "fastrand", + "getrandom 0.4.2", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2104,9 +2187,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.51.1" +version = "1.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" +checksum = "a91135f59b1cbf38c91e73cf3386fca9bb77915c45ce2771460c9d92f0f3d776" dependencies = [ "bytes", "libc", @@ -2175,9 +2258,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.17.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicode-bidi" @@ -2187,9 +2270,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-normalization" @@ -2238,9 +2321,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" @@ -2274,46 +2357,32 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" dependencies = [ "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", "once_cell", - "proc-macro2", - "quote", - "syn", + "rustversion", + "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" dependencies = [ - "cfg-if", "js-sys", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2321,22 +2390,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-encoder" @@ -2374,9 +2446,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" dependencies = [ "js-sys", "wasm-bindgen", @@ -2460,15 +2532,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.59.0" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index eaf86a7..274b467 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,34 +1,3 @@ -[package] -name = "rust_lib_twonly" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib", "staticlib"] - -[dependencies] -flutter_rust_bridge = "=2.12.0" -thiserror = "2.0.18" -sqlx = { version = "0.9.0-alpha.1", default-features = false, features = [ - "runtime-tokio", - "sqlite", - "migrate", - "macros", - "chrono", - "derive", - "json", -] } -tokio = { version = "1.44", features = ["full"] } -tracing = "0.1.44" -serde = "1.0.228" -prost = "0.14.1" -rand = "0.10.1" -blahaj = "0.6.0" -postcard = { version = "1.1.3", features = ["alloc"] } - -[dev-dependencies] -pretty_env_logger = "0.5.0" - - -[build-dependencies] -prost-build = "0.14.1" +[workspace] +members = ["protocols", "core"] +resolver = "3" diff --git a/rust/build.rs b/rust/build.rs deleted file mode 100644 index 135361e..0000000 --- a/rust/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -use std::io::Result; -fn main() -> Result<()> { - prost_build::compile_protos(&["src/user_discovery/types.proto"], &["src/"])?; - Ok(()) -} diff --git a/rust/core/.gitignore b/rust/core/.gitignore new file mode 100644 index 0000000..dfb400c --- /dev/null +++ b/rust/core/.gitignore @@ -0,0 +1,3 @@ +/target + +tests/tmp_testing.db* \ No newline at end of file diff --git a/rust/core/Cargo.toml b/rust/core/Cargo.toml new file mode 100644 index 0000000..1f76cb6 --- /dev/null +++ b/rust/core/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "rust_lib_twonly" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "staticlib"] + +[dependencies] +flutter_rust_bridge = "=2.12.0" +thiserror = "2.0.18" +sqlx = { version = "0.9.0-alpha.1", default-features = false, features = [ + "runtime-tokio", + "sqlite", + "migrate", + "macros", + "chrono", + "derive", + "json", +] } +tokio = { version = "1.44", features = ["full"] } +tracing = "0.1.44" +rand = "0.10.1" +protocols = { path = "../protocols" } + +[dev-dependencies] +pretty_env_logger = "0.5.0" + + +[build-dependencies] +prost-build = "0.14.1" diff --git a/rust/src/twonly/error.rs b/rust/core/src/bridge/error.rs similarity index 100% rename from rust/src/twonly/error.rs rename to rust/core/src/bridge/error.rs diff --git a/rust/src/twonly/log/mod.rs b/rust/core/src/bridge/log/mod.rs similarity index 100% rename from rust/src/twonly/log/mod.rs rename to rust/core/src/bridge/log/mod.rs diff --git a/rust/src/twonly/mod.rs b/rust/core/src/bridge/mod.rs similarity index 71% rename from rust/src/twonly/mod.rs rename to rust/core/src/bridge/mod.rs index bf4e0f9..fbcc08b 100644 --- a/rust/src/twonly/mod.rs +++ b/rust/core/src/bridge/mod.rs @@ -1,19 +1,33 @@ -pub mod database; pub mod error; -use crate::twonly::{database::contact::Contact, error::TwonlyError}; -use database::Database; +mod user_discovery; +use crate::database::contact::Contact; +use crate::database::Database; use error::Result; +use error::TwonlyError; +use flutter_rust_bridge::frb; use std::sync::Arc; use tokio::sync::OnceCell; +use protocols::user_discovery::traits::OtherPromotion; + +#[frb(mirror(OtherPromotion))] +pub struct _OtherPromotion { + pub promotion_id: u32, + pub public_id: u64, + pub from_contact_id: i64, + pub threshold: u8, + pub announcement_share: Vec, + pub public_key_verified_timestamp: Option, +} + pub struct TwonlyConfig { pub database_path: String, } -struct Twonly { +pub(crate) struct Twonly { #[allow(dead_code)] pub(crate) config: TwonlyConfig, - database: Arc, + pub(crate) database: Arc, } static GLOBAL_TWONLY: OnceCell = OnceCell::const_new(); @@ -41,15 +55,19 @@ pub async fn get_all_contacts() -> Result> { Contact::get_all_contacts(twonly.database.as_ref()).await } +pub fn load_promotions() -> OtherPromotion { + todo!() +} + #[cfg(test)] pub(crate) mod tests { use super::error::Result; use super::Twonly; use std::path::PathBuf; - use crate::twonly::{get_instance, initialize_twonly, TwonlyConfig}; + use super::{get_instance, initialize_twonly, TwonlyConfig}; - pub(super) async fn initialize_twonly_for_testing() -> Result<&'static Twonly> { + pub(crate) async fn initialize_twonly_for_testing() -> Result<&'static Twonly> { let default_twonly_database = PathBuf::from("tests/testing.db"); if !default_twonly_database.is_file() { diff --git a/rust/core/src/bridge/user_discovery.rs b/rust/core/src/bridge/user_discovery.rs new file mode 100644 index 0000000..29e128e --- /dev/null +++ b/rust/core/src/bridge/user_discovery.rs @@ -0,0 +1,72 @@ +use protocols::user_discovery::error::{Result, UserDiscoveryError}; +use protocols::user_discovery::traits::{AnnouncedUser, OtherPromotion, UserDiscoveryStore}; +use protocols::user_discovery::UserID; +use std::collections::HashMap; + +struct UserDiscoveryDatabaseStore {} + +impl UserDiscoveryStore for UserDiscoveryDatabaseStore { + fn get_config(&self) -> Result> { + todo!() + } + + fn update_config(&self, update: Vec) -> Result<()> { + todo!() + } + + fn set_shares(&self, shares: Vec>) -> Result<()> { + todo!() + } + + fn get_share_for_contact(&self, contact_id: UserID) -> Result> { + todo!() + } + + fn push_own_promotion( + &self, + contact_id: UserID, + version: u32, + promotion: Vec, + ) -> Result<()> { + todo!() + } + + fn get_own_promotions_after_version(&self, version: u32) -> Result>> { + todo!() + } + + fn store_other_promotion(&self, promotion: OtherPromotion) -> Result<()> { + todo!() + } + + fn get_other_promotions_by_public_id(&self, public_id: u64) -> Vec { + todo!() + } + + fn get_announced_user_by_public_id(&self, public_id: u64) -> Result> { + todo!() + } + + fn push_new_user_relation( + &self, + from_contact_id: UserID, + announced_user: AnnouncedUser, + public_key_verified_timestamp: Option, + ) -> Result<()> { + todo!() + } + + fn get_all_announced_users( + &self, + ) -> Result)>>> { + todo!() + } + + fn get_contact_version(&self, contact_id: UserID) -> Result>> { + todo!() + } + + fn set_contact_version(&self, contact_id: UserID, update: Vec) -> Result<()> { + todo!() + } +} diff --git a/rust/src/twonly/database/contact.rs b/rust/core/src/database/contact.rs similarity index 89% rename from rust/src/twonly/database/contact.rs rename to rust/core/src/database/contact.rs index 084d3e0..710c199 100644 --- a/rust/src/twonly/database/contact.rs +++ b/rust/core/src/database/contact.rs @@ -1,7 +1,8 @@ // use sqlx::types::chrono::{DateTime, Utc}; use sqlx::FromRow; -use crate::twonly::{database::Database, error::Result}; +use super::Database; +use crate::bridge::error::Result; #[derive(FromRow, Clone, Debug)] struct ContactRow { @@ -37,7 +38,8 @@ impl Contact { #[cfg(test)] mod tests { - use crate::twonly::{database::contact::Contact, tests::initialize_twonly_for_testing}; + use crate::bridge::tests::initialize_twonly_for_testing; + use crate::database::contact::Contact; #[tokio::test] async fn test_get_all_contacts() { diff --git a/rust/src/twonly/database/mod.rs b/rust/core/src/database/mod.rs similarity index 88% rename from rust/src/twonly/database/mod.rs rename to rust/core/src/database/mod.rs index d35dff7..db87356 100644 --- a/rust/src/twonly/database/mod.rs +++ b/rust/core/src/database/mod.rs @@ -1,13 +1,8 @@ -pub mod contact; - -use crate::twonly::error::TwonlyError; - -use super::error::Result; -use sqlx::{ - migrate::MigrateDatabase, - sqlite::{SqliteConnectOptions, SqlitePoolOptions}, - ConnectOptions, Sqlite, SqlitePool, -}; +pub(crate) mod contact; +use crate::bridge::error::{Result, TwonlyError}; +use sqlx::migrate::MigrateDatabase; +use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions}; +use sqlx::{ConnectOptions, Sqlite, SqlitePool}; use std::time::Duration; pub(crate) struct Database { diff --git a/rust/src/frb_generated.rs b/rust/core/src/frb_generated.rs similarity index 62% rename from rust/src/frb_generated.rs rename to rust/core/src/frb_generated.rs index 60ced76..536a988 100644 --- a/rust/src/frb_generated.rs +++ b/rust/core/src/frb_generated.rs @@ -38,7 +38,7 @@ flutter_rust_bridge::frb_generated_boilerplate!( default_rust_auto_opaque = RustAutoOpaqueMoi, ); pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.12.0"; -pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 741438464; +pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 776002844; // Section: executor @@ -46,7 +46,7 @@ flutter_rust_bridge::frb_generated_default_handler!(); // Section: wire_funcs -fn wire__crate__twonly__get_all_contacts_impl( +fn wire__crate__bridge__get_all_contacts_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, rust_vec_len_: i32, @@ -72,7 +72,7 @@ fn wire__crate__twonly__get_all_contacts_impl( move |context| async move { transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>( (move || async move { - let output_ok = crate::twonly::get_all_contacts().await?; + let output_ok = crate::bridge::get_all_contacts().await?; Ok(output_ok) })() .await, @@ -81,7 +81,7 @@ fn wire__crate__twonly__get_all_contacts_impl( }, ) } -fn wire__crate__twonly__initialize_twonly_impl( +fn wire__crate__bridge__initialize_twonly_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, rust_vec_len_: i32, @@ -103,12 +103,12 @@ fn wire__crate__twonly__initialize_twonly_impl( }; let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message); - let api_config = ::sse_decode(&mut deserializer); + let api_config = ::sse_decode(&mut deserializer); deserializer.end(); move |context| async move { transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>( (move || async move { - let output_ok = crate::twonly::initialize_twonly(api_config).await?; + let output_ok = crate::bridge::initialize_twonly(api_config).await?; Ok(output_ok) })() .await, @@ -117,6 +117,51 @@ fn wire__crate__twonly__initialize_twonly_impl( }, ) } +fn wire__crate__bridge__load_promotions_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "load_promotions", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + deserializer.end(); + move |context| { + transform_result_sse::<_, ()>((move || { + let output_ok = Result::<_, ()>::Ok(crate::bridge::load_promotions())?; + Ok(output_ok) + })()) + } + }, + ) +} + +// Section: static_checks + +#[allow(clippy::unnecessary_literal_unwrap)] +const _: fn() = || { + let OtherPromotion = None::.unwrap(); + let _: u32 = OtherPromotion.promotion_id; + let _: u64 = OtherPromotion.public_id; + let _: i64 = OtherPromotion.from_contact_id; + let _: u8 = OtherPromotion.threshold; + let _: Vec = OtherPromotion.announcement_share; + let _: Option = OtherPromotion.public_key_verified_timestamp; +}; // Section: dart2rust @@ -136,12 +181,12 @@ impl SseDecode for String { } } -impl SseDecode for crate::twonly::database::contact::Contact { +impl SseDecode for crate::database::contact::Contact { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { let mut var_userId = ::sse_decode(deserializer); let mut var_username = ::sse_decode(deserializer); - return crate::twonly::database::contact::Contact { + return crate::database::contact::Contact { user_id: var_userId, username: var_username, }; @@ -155,13 +200,13 @@ impl SseDecode for i64 { } } -impl SseDecode for Vec { +impl SseDecode for Vec { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { let mut len_ = ::sse_decode(deserializer); let mut ans_ = Vec::with_capacity(len_ as usize); for idx_ in 0..len_ { - ans_.push(::sse_decode( + ans_.push(::sse_decode( deserializer, )); } @@ -181,16 +226,61 @@ impl SseDecode for Vec { } } -impl SseDecode for crate::twonly::TwonlyConfig { +impl SseDecode for Option { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + if (::sse_decode(deserializer)) { + return Some(::sse_decode(deserializer)); + } else { + return None; + } + } +} + +impl SseDecode for crate::bridge::OtherPromotion { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut var_promotionId = ::sse_decode(deserializer); + let mut var_publicId = ::sse_decode(deserializer); + let mut var_fromContactId = ::sse_decode(deserializer); + let mut var_threshold = ::sse_decode(deserializer); + let mut var_announcementShare = >::sse_decode(deserializer); + let mut var_publicKeyVerifiedTimestamp = >::sse_decode(deserializer); + return crate::bridge::OtherPromotion { + promotion_id: var_promotionId, + public_id: var_publicId, + from_contact_id: var_fromContactId, + threshold: var_threshold, + announcement_share: var_announcementShare, + public_key_verified_timestamp: var_publicKeyVerifiedTimestamp, + }; + } +} + +impl SseDecode for crate::bridge::TwonlyConfig { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { let mut var_databasePath = ::sse_decode(deserializer); - return crate::twonly::TwonlyConfig { + return crate::bridge::TwonlyConfig { database_path: var_databasePath, }; } } +impl SseDecode for u32 { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + deserializer.cursor.read_u32::().unwrap() + } +} + +impl SseDecode for u64 { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + deserializer.cursor.read_u64::().unwrap() + } +} + impl SseDecode for u8 { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -226,8 +316,9 @@ fn pde_ffi_dispatcher_primary_impl( ) { // Codec=Pde (Serialization + dispatch), see doc to use other codecs match func_id { - 1 => wire__crate__twonly__get_all_contacts_impl(port, ptr, rust_vec_len, data_len), - 2 => wire__crate__twonly__initialize_twonly_impl(port, ptr, rust_vec_len, data_len), + 1 => wire__crate__bridge__get_all_contacts_impl(port, ptr, rust_vec_len, data_len), + 2 => wire__crate__bridge__initialize_twonly_impl(port, ptr, rust_vec_len, data_len), + 3 => wire__crate__bridge__load_promotions_impl(port, ptr, rust_vec_len, data_len), _ => unreachable!(), } } @@ -247,7 +338,7 @@ fn pde_ffi_dispatcher_sync_impl( // Section: rust2dart // Codec=Dco (DartCObject based), see doc to use other codecs -impl flutter_rust_bridge::IntoDart for crate::twonly::database::contact::Contact { +impl flutter_rust_bridge::IntoDart for crate::database::contact::Contact { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { [ self.user_id.into_into_dart().into_dart(), @@ -257,27 +348,55 @@ impl flutter_rust_bridge::IntoDart for crate::twonly::database::contact::Contact } } impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive - for crate::twonly::database::contact::Contact + for crate::database::contact::Contact { } -impl flutter_rust_bridge::IntoIntoDart - for crate::twonly::database::contact::Contact +impl flutter_rust_bridge::IntoIntoDart + for crate::database::contact::Contact { - fn into_into_dart(self) -> crate::twonly::database::contact::Contact { + fn into_into_dart(self) -> crate::database::contact::Contact { self } } // Codec=Dco (DartCObject based), see doc to use other codecs -impl flutter_rust_bridge::IntoDart for crate::twonly::TwonlyConfig { +impl flutter_rust_bridge::IntoDart for FrbWrapper { + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + [ + self.0.promotion_id.into_into_dart().into_dart(), + self.0.public_id.into_into_dart().into_dart(), + self.0.from_contact_id.into_into_dart().into_dart(), + self.0.threshold.into_into_dart().into_dart(), + self.0.announcement_share.into_into_dart().into_dart(), + self.0 + .public_key_verified_timestamp + .into_into_dart() + .into_dart(), + ] + .into_dart() + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive + for FrbWrapper +{ +} +impl flutter_rust_bridge::IntoIntoDart> + for crate::bridge::OtherPromotion +{ + fn into_into_dart(self) -> FrbWrapper { + self.into() + } +} +// Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart for crate::bridge::TwonlyConfig { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { [self.database_path.into_into_dart().into_dart()].into_dart() } } -impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::twonly::TwonlyConfig {} -impl flutter_rust_bridge::IntoIntoDart - for crate::twonly::TwonlyConfig +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::bridge::TwonlyConfig {} +impl flutter_rust_bridge::IntoIntoDart + for crate::bridge::TwonlyConfig { - fn into_into_dart(self) -> crate::twonly::TwonlyConfig { + fn into_into_dart(self) -> crate::bridge::TwonlyConfig { self } } @@ -296,7 +415,7 @@ impl SseEncode for String { } } -impl SseEncode for crate::twonly::database::contact::Contact { +impl SseEncode for crate::database::contact::Contact { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { ::sse_encode(self.user_id, serializer); @@ -311,12 +430,12 @@ impl SseEncode for i64 { } } -impl SseEncode for Vec { +impl SseEncode for Vec { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { ::sse_encode(self.len() as _, serializer); for item in self { - ::sse_encode(item, serializer); + ::sse_encode(item, serializer); } } } @@ -331,13 +450,49 @@ impl SseEncode for Vec { } } -impl SseEncode for crate::twonly::TwonlyConfig { +impl SseEncode for Option { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + ::sse_encode(self.is_some(), serializer); + if let Some(value) = self { + ::sse_encode(value, serializer); + } + } +} + +impl SseEncode for crate::bridge::OtherPromotion { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + ::sse_encode(self.promotion_id, serializer); + ::sse_encode(self.public_id, serializer); + ::sse_encode(self.from_contact_id, serializer); + ::sse_encode(self.threshold, serializer); + >::sse_encode(self.announcement_share, serializer); + >::sse_encode(self.public_key_verified_timestamp, serializer); + } +} + +impl SseEncode for crate::bridge::TwonlyConfig { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { ::sse_encode(self.database_path, serializer); } } +impl SseEncode for u32 { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + serializer.cursor.write_u32::(self).unwrap(); + } +} + +impl SseEncode for u64 { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + serializer.cursor.write_u64::(self).unwrap(); + } +} + impl SseEncode for u8 { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { diff --git a/rust/core/src/lib.rs b/rust/core/src/lib.rs new file mode 100644 index 0000000..ac8b48f --- /dev/null +++ b/rust/core/src/lib.rs @@ -0,0 +1,3 @@ +pub mod bridge; +mod database; +mod frb_generated; diff --git a/rust/tests/testing.db b/rust/core/tests/testing.db similarity index 100% rename from rust/tests/testing.db rename to rust/core/tests/testing.db diff --git a/rust/protocols/Cargo.toml b/rust/protocols/Cargo.toml new file mode 100644 index 0000000..d0e95b3 --- /dev/null +++ b/rust/protocols/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "protocols" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["rlib", "cdylib", "staticlib"] + +[dependencies] +thiserror = "2.0.18" +tracing = "0.1.44" +serde = "1.0.228" +prost = "0.14.1" +rand = "0.10.1" +blahaj = "0.6.0" +postcard = { version = "1.1.3", features = ["alloc"] } +base64 = "0.22.1" +hmac = "0.13.0" +sha2 = "0.11.0" + +[dev-dependencies] +pretty_env_logger = "0.5.0" + +[build-dependencies] +prost-build = "0.14.1" diff --git a/rust/protocols/build.rs b/rust/protocols/build.rs new file mode 100644 index 0000000..12e4744 --- /dev/null +++ b/rust/protocols/build.rs @@ -0,0 +1,11 @@ +use std::io::Result; +fn main() -> Result<()> { + prost_build::compile_protos( + &[ + "src/user_discovery/types.proto", + "src/key_verification/types.proto", + ], + &["src/"], + )?; + Ok(()) +} diff --git a/rust/protocols/src/key_verification/error.rs b/rust/protocols/src/key_verification/error.rs new file mode 100644 index 0000000..a23b1d1 --- /dev/null +++ b/rust/protocols/src/key_verification/error.rs @@ -0,0 +1,30 @@ +use prost::DecodeError; +use thiserror::Error; + +pub type Result = core::result::Result; + +#[derive(Error, Debug)] +pub enum KeyVerificationError { + #[error("The prefix deeplink url must start with https:// and end with a #")] + InvalidDeeplinkPrefix, + + #[error("Invalid qr text")] + InvalidQrText, + + #[error( + "Contact user_id is known and the stored public_key does not match the received user id" + )] + InvalidPublicKeyAndUserIdCombination, + + #[error("Store error: `{0}`")] + Store(String), + + #[error("`{0}`")] + Base64(#[from] base64::DecodeError), + + #[error("`{0}`")] + Prost(#[from] DecodeError), + + #[error("`{0}`")] + Hmac(#[from] hmac::digest::InvalidLength), +} diff --git a/rust/protocols/src/key_verification/mod.rs b/rust/protocols/src/key_verification/mod.rs new file mode 100644 index 0000000..f349347 --- /dev/null +++ b/rust/protocols/src/key_verification/mod.rs @@ -0,0 +1,194 @@ +use crate::key_verification::{error::KeyVerificationError, traits::KeyVerificationStore}; +use crate::user_discovery::UserID; +use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _}; +use error::Result; +use hmac::{Hmac, KeyInit, Mac}; +use prost::Message; +use sha2::Sha256; + +pub(crate) mod error; +pub mod stores; +pub mod traits; + +include!(concat!(env!("OUT_DIR"), "/key_verification.rs")); + +pub struct KeyVerificationConfig { + /// The link prefix for the qr code which should be registered as a deeplink on Android and a universal link on iOS + /// The link MUST start with a https:// and end with a # + /// The link should contain the username of the user so the application can show the scanned user without internet + /// Example: https://me.twonly.eu/tobi# + deeplink_prefix: String, + /// The user ID used to calculate the verification proof + user_id: UserID, + /// The public_key of the user to calculate the verification proof + public_key: Vec, +} + +pub struct ScannedUser { + pub user_id: UserID, + pub public_key: Vec, + pub verification_proof: Vec, +} + +pub struct KeyVerification { + store: Store, + config: KeyVerificationConfig, +} + +impl KeyVerification { + pub fn new(store: Store, config: KeyVerificationConfig) -> Result> { + if !config.deeplink_prefix.starts_with("https://") || !config.deeplink_prefix.ends_with("#") + { + return Err(KeyVerificationError::InvalidDeeplinkPrefix); + } + Ok(Self { store, config }) + } + + /// Generates the a string which should be displayed in the UI so others can scan it. + pub fn generate_qr_text(&self) -> Result { + // 10 Bytes should be enough. Tokens are only valid for one day and then deleted. + let secret_verification_token: Vec = rand::random_iter().take(16).collect(); + + self.store + .push_new_secret_verification_token(&secret_verification_token)?; + + let verification_data = VerificationData { + user_id: self.config.user_id, + public_key: self.config.public_key.clone(), + secret_verification_token, + }; + + let verification_data_bytes = verification_data.encode_to_vec(); + let encoded = URL_SAFE_NO_PAD.encode(verification_data_bytes); + + Ok(format!("{}{}", self.config.deeplink_prefix, encoded)) + } + + /// Handles the scanned qr code text and creates a response message + /// which can be send to the other person + pub fn get_user_from_scanned_qr_text(&self, received_text: &str) -> Result { + let splitted: Vec<_> = received_text.split('#').collect(); + if splitted.len() != 2 { + tracing::info!("Scanned qr text does not contain a #"); + return Err(KeyVerificationError::InvalidQrText); + } + let verification_data_bytes = URL_SAFE_NO_PAD.decode(splitted[1])?; + let verification_data = VerificationData::decode(verification_data_bytes.as_slice())?; + + let mut mac = Hmac::::new_from_slice(&verification_data.secret_verification_token)?; + mac.update(&self.config.user_id.to_le_bytes()); + mac.update(&self.config.public_key); + mac.update(&verification_data.user_id.to_le_bytes()); + mac.update(&verification_data.public_key); + + let verification_proof = mac.finalize().into_bytes().to_vec(); + + Ok(ScannedUser { + user_id: verification_data.user_id, + public_key: verification_data.public_key, + verification_proof, + }) + } + + /// Checks whether the received verification proof is valid + pub fn is_received_verification_proof_valid( + &self, + from_user_id: UserID, + public_key: Vec, + verification_proof: Vec, + ) -> Result { + let verification_tokens = self.store.get_all_valid_verification_tokens()?; + + for verification_token in &verification_tokens { + let calculated_verification_proof = { + let mut mac = Hmac::::new_from_slice(verification_token)?; + mac.update(&from_user_id.to_le_bytes()); + mac.update(&public_key); + mac.update(&self.config.user_id.to_le_bytes()); + mac.update(&self.config.public_key); + mac.finalize().into_bytes().to_vec() + }; + + if calculated_verification_proof == verification_proof { + return Ok(true); + } + } + + Ok(false) + } +} + +#[cfg(test)] +mod tests { + use crate::key_verification::{stores::InMemoryStore, KeyVerification, KeyVerificationConfig}; + + #[test] + fn test_key_verification() { + let _ = pretty_env_logger::try_init(); + + const ALICE_ID: i64 = 10; + const BOB_ID: i64 = 11; + + let alice_kv = KeyVerification::new( + InMemoryStore::default(), + KeyVerificationConfig { + user_id: ALICE_ID, + public_key: vec![ALICE_ID as u8; 32], + deeplink_prefix: "https://me.twonly.eu/alice#".into(), + }, + ) + .unwrap(); + + let bob_kv = KeyVerification::new( + InMemoryStore::default(), + KeyVerificationConfig { + user_id: BOB_ID, + public_key: vec![BOB_ID as u8; 32], + deeplink_prefix: "https://me.twonly.eu/bob#".into(), + }, + ) + .unwrap(); + + let qr_code_text = alice_kv.generate_qr_text().unwrap(); + assert_eq!(qr_code_text.len(), 99); + + tracing::debug!("Generated QR-Code-Link: {qr_code_text}"); + + let scanned_user = bob_kv.get_user_from_scanned_qr_text(&qr_code_text).unwrap(); + + // THIS must be done by the application + assert_eq!(scanned_user.user_id, ALICE_ID); + assert_eq!(scanned_user.public_key, vec![ALICE_ID as u8; 32]); + + // SEND scanned_user.verification_proof over the establish e2ee protected session if public_key verification was valid. + + let valid_verification_proof = alice_kv + .is_received_verification_proof_valid( + BOB_ID, + vec![BOB_ID as u8; 32], + scanned_user.verification_proof.clone(), + ) + .unwrap(); + + assert_eq!(valid_verification_proof, true); + + let valid_verification_proof = alice_kv + .is_received_verification_proof_valid( + BOB_ID, + vec![(BOB_ID + 1) as u8; 32], + scanned_user.verification_proof.clone(), + ) + .unwrap(); + + assert_eq!(valid_verification_proof, false); + + let mut modified_proof = scanned_user.verification_proof; + modified_proof[0] = modified_proof[0] + 1; + + let valid_verification_proof = alice_kv + .is_received_verification_proof_valid(BOB_ID, vec![BOB_ID as u8; 32], modified_proof) + .unwrap(); + + assert_eq!(valid_verification_proof, false); + } +} diff --git a/rust/protocols/src/key_verification/stores/in_memory_store.rs b/rust/protocols/src/key_verification/stores/in_memory_store.rs new file mode 100644 index 0000000..160fbfb --- /dev/null +++ b/rust/protocols/src/key_verification/stores/in_memory_store.rs @@ -0,0 +1,22 @@ +use std::sync::{Arc, Mutex}; + +use crate::key_verification::{error::Result, traits::KeyVerificationStore}; + +#[derive(Default)] +pub struct InMemoryStore { + verification_tokens: Arc>>>, +} + +impl KeyVerificationStore for InMemoryStore { + fn push_new_secret_verification_token(&self, token: &[u8]) -> Result<()> { + self.verification_tokens + .lock() + .unwrap() + .push(token.to_vec()); + Ok(()) + } + + fn get_all_valid_verification_tokens(&self) -> Result>> { + Ok(self.verification_tokens.lock().unwrap().clone()) + } +} diff --git a/rust/protocols/src/key_verification/stores/mod.rs b/rust/protocols/src/key_verification/stores/mod.rs new file mode 100644 index 0000000..30b1f14 --- /dev/null +++ b/rust/protocols/src/key_verification/stores/mod.rs @@ -0,0 +1,3 @@ +mod in_memory_store; + +pub use in_memory_store::InMemoryStore; diff --git a/rust/protocols/src/key_verification/traits.rs b/rust/protocols/src/key_verification/traits.rs new file mode 100644 index 0000000..1689e3a --- /dev/null +++ b/rust/protocols/src/key_verification/traits.rs @@ -0,0 +1,7 @@ +use super::error::Result; +pub trait KeyVerificationStore { + fn push_new_secret_verification_token(&self, token: &[u8]) -> Result<()>; + /// This function should return all tokens from the last 24h + /// All other tokens can be removed from the database + fn get_all_valid_verification_tokens(&self) -> Result>>; +} diff --git a/rust/protocols/src/key_verification/types.proto b/rust/protocols/src/key_verification/types.proto new file mode 100644 index 0000000..bd515eb --- /dev/null +++ b/rust/protocols/src/key_verification/types.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package key_verification; + +message VerificationData { + int64 user_id = 1; + bytes public_key = 2; + bytes secret_verification_token = 3; +} + +message VerificationMessage { + bytes calculated_mac = 1; +} \ No newline at end of file diff --git a/rust/protocols/src/lib.rs b/rust/protocols/src/lib.rs new file mode 100644 index 0000000..8564130 --- /dev/null +++ b/rust/protocols/src/lib.rs @@ -0,0 +1,3 @@ +pub mod key_verification; +pub mod passwordless_recovery; +pub mod user_discovery; diff --git a/rust/src/passwordless_recovery/mod.rs b/rust/protocols/src/passwordless_recovery/mod.rs similarity index 100% rename from rust/src/passwordless_recovery/mod.rs rename to rust/protocols/src/passwordless_recovery/mod.rs diff --git a/rust/src/passwordless_recovery/traits.rs b/rust/protocols/src/passwordless_recovery/traits.rs similarity index 100% rename from rust/src/passwordless_recovery/traits.rs rename to rust/protocols/src/passwordless_recovery/traits.rs diff --git a/rust/src/user_discovery/README.md b/rust/protocols/src/user_discovery/README.md similarity index 100% rename from rust/src/user_discovery/README.md rename to rust/protocols/src/user_discovery/README.md diff --git a/rust/src/user_discovery/error.rs b/rust/protocols/src/user_discovery/error.rs similarity index 92% rename from rust/src/user_discovery/error.rs rename to rust/protocols/src/user_discovery/error.rs index 0c0246e..7ef9b10 100644 --- a/rust/src/user_discovery/error.rs +++ b/rust/protocols/src/user_discovery/error.rs @@ -5,6 +5,9 @@ pub type Result = core::result::Result; #[derive(Error, Debug)] pub enum UserDiscoveryError { + #[error("Store error: `{0}`")] + Store(String), + #[error("The encrypted announcement data contains malicious data: `{0}`")] MaliciousAnnouncementData(String), diff --git a/rust/src/user_discovery/mod.rs b/rust/protocols/src/user_discovery/mod.rs similarity index 99% rename from rust/src/user_discovery/mod.rs rename to rust/protocols/src/user_discovery/mod.rs index 89372fa..4aa1f00 100644 --- a/rust/src/user_discovery/mod.rs +++ b/rust/protocols/src/user_discovery/mod.rs @@ -1,4 +1,4 @@ -mod error; +pub mod error; pub mod stores; pub mod traits; @@ -22,7 +22,7 @@ static TRANSMITTED_NETWORK_BYTES: std::sync::OnceLock> = /// the types.proto pub type UserID = i64; -include!(concat!(env!("OUT_DIR"), "/_.rs")); +include!(concat!(env!("OUT_DIR"), "/user_discovery.rs")); #[derive(Serialize, Deserialize, Clone, Debug)] struct UserDiscoveryConfig { @@ -245,6 +245,7 @@ impl UserDiscovery stored_version.promotion) } + #[cfg(test)] pub(crate) fn get_contact_version(&self, contact_id: UserID) -> Result>> { self.store.get_contact_version(contact_id) } @@ -687,10 +688,10 @@ mod tests { } } - #[tokio::test] - async fn test_initialize_user_discovery() { - pretty_env_logger::init(); - let counter = TRANSMITTED_NETWORK_BYTES.get_or_init(|| std::sync::Mutex::new(0)); + #[test] + fn test_initialize_user_discovery() { + let _ = pretty_env_logger::try_init(); + let _ = TRANSMITTED_NETWORK_BYTES.get_or_init(|| std::sync::Mutex::new(0)); let users = TestUsers::get(); diff --git a/rust/src/user_discovery/stores/in_memory_store.rs b/rust/protocols/src/user_discovery/stores/in_memory_store.rs similarity index 100% rename from rust/src/user_discovery/stores/in_memory_store.rs rename to rust/protocols/src/user_discovery/stores/in_memory_store.rs diff --git a/rust/src/user_discovery/stores/mod.rs b/rust/protocols/src/user_discovery/stores/mod.rs similarity index 100% rename from rust/src/user_discovery/stores/mod.rs rename to rust/protocols/src/user_discovery/stores/mod.rs diff --git a/rust/src/user_discovery/traits.rs b/rust/protocols/src/user_discovery/traits.rs similarity index 100% rename from rust/src/user_discovery/traits.rs rename to rust/protocols/src/user_discovery/traits.rs diff --git a/rust/src/user_discovery/types.proto b/rust/protocols/src/user_discovery/types.proto similarity index 97% rename from rust/src/user_discovery/types.proto rename to rust/protocols/src/user_discovery/types.proto index 9237586..50dc1cc 100644 --- a/rust/src/user_discovery/types.proto +++ b/rust/protocols/src/user_discovery/types.proto @@ -1,4 +1,5 @@ syntax = "proto3"; +package user_discovery; message UserDiscoveryVersion { uint32 announcement = 1; diff --git a/rust/src/key_verification/mod.rs b/rust/src/key_verification/mod.rs deleted file mode 100644 index c347d67..0000000 --- a/rust/src/key_verification/mod.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::key_verification::traits::KeyVerificationStore; - -pub mod traits; - -pub struct KeyVerificationConfig { - /// The link prefix for the qr code which should be registered as a deeplink on Android and a universal link on iOS - deeplink_prefix: String, -} - -struct KeyVerification { - store: Store, - config: KeyVerificationConfig, -} - -impl KeyVerification { - pub fn new(store: Store, config: KeyVerificationConfig) -> KeyVerification { - Self { store, config } - } - - /// Generates the a string which should be displayed in the UI so others can scan it. - pub fn generate_qr_code_data() -> String { - todo!(); - } - - /// Generates the a string which should be displayed in the UI so others can scan it. - pub fn handle_qr_code_data() -> String { - todo!(); - } -} diff --git a/rust/src/key_verification/traits.rs b/rust/src/key_verification/traits.rs deleted file mode 100644 index 1fc4c49..0000000 --- a/rust/src/key_verification/traits.rs +++ /dev/null @@ -1 +0,0 @@ -pub trait KeyVerificationStore {} diff --git a/rust/src/lib.rs b/rust/src/lib.rs deleted file mode 100644 index 0b278cd..0000000 --- a/rust/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod frb_generated; -mod key_verification; -mod passwordless_recovery; -mod twonly; -mod user_discovery;