From 4d943eca1c5aa7f511246d29bddd94e1c298ce19 Mon Sep 17 00:00:00 2001 From: otsmr Date: Sun, 21 Jun 2026 02:07:09 +0200 Subject: [PATCH] enable and handle heartbeath --- README.md | 2 - lib/core/bridge/callbacks/user_discovery.dart | 173 + lib/core/bridge/wrapper.dart | 37 + lib/core/bridge/wrapper/key_manager.dart | 4 + lib/core/frb_generated.dart | 1014 +- lib/core/frb_generated.io.dart | 89 + lib/core/frb_generated.web.dart | 89 + .../schemas/twonly_db/drift_schema_v21.json | 3127 +++++ lib/src/database/tables/contacts.table.dart | 4 + lib/src/database/twonly.db.dart | 12 +- lib/src/database/twonly.db.g.dart | 194 + lib/src/database/twonly.db.steps.dart | 542 + lib/src/model/json/userdata.model.dart | 29 +- lib/src/model/json/userdata.model.g.dart | 34 +- .../api/websocket/client_to_server.pb.dart | 109 +- .../websocket/client_to_server.pbjson.dart | 88 +- .../client/generated/messages.pb.dart | 177 + .../client/generated/messages.pbjson.dart | 215 +- .../generated/passwordless_recovery.pb.dart | 559 + .../passwordless_recovery.pbenum.dart | 11 + .../passwordless_recovery.pbjson.dart | 182 + lib/src/model/protobuf/client/messages.proto | 15 +- .../client/passwordless_recovery.proto | 50 +- lib/src/services/api.service.dart | 16 + lib/src/services/api/server_messages.api.dart | 19 + .../passwordless_recovery.service.dart | 396 +- lib/src/utils/misc.dart | 23 + rust/build.rs | 1 - rust/src/bridge/wrapper/key_manager.rs | 8 + rust/src/bridge/wrapper/mod.rs | 26 + rust/src/frb_generated.rs | 506 +- rust/src/lib.rs | 1 - rust/src/passwordless_recovery/mod.rs | 12 - scripts/generate_proto.sh | 4 +- test/drift/twonly_db/generated/schema.dart | 4 + .../drift/twonly_db/generated/schema_v21.dart | 11000 ++++++++++++++++ test/features/link_parser_test.dart | 14 - .../passwordless_recovery_service_test.dart | 610 + 38 files changed, 19135 insertions(+), 261 deletions(-) create mode 100644 lib/core/bridge/callbacks/user_discovery.dart create mode 100644 lib/core/bridge/wrapper.dart create mode 100644 lib/src/database/schemas/twonly_db/drift_schema_v21.json create mode 100644 lib/src/model/protobuf/client/generated/passwordless_recovery.pb.dart create mode 100644 lib/src/model/protobuf/client/generated/passwordless_recovery.pbenum.dart create mode 100644 lib/src/model/protobuf/client/generated/passwordless_recovery.pbjson.dart rename rust/src/passwordless_recovery/types.proto => lib/src/model/protobuf/client/passwordless_recovery.proto (58%) delete mode 100644 rust/src/passwordless_recovery/mod.rs create mode 100644 test/drift/twonly_db/generated/schema_v21.dart create mode 100644 test/services/passwordless_recovery_service_test.dart diff --git a/README.md b/README.md index 0b1e68ee..590d3ac0 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ If you decide to give twonly a try, please keep in mind that it is still in its - End-to-End encryption using the [Signal Protocol](https://de.wikipedia.org/wiki/Signal-Protokoll) - Open Source and can be downloaded directly from GitHub - No email or phone number required to register -- Privacy friendly - Everything is stored on the device - The backend is hosted exclusively in Europe ## Roadmap @@ -43,7 +42,6 @@ If you decide to give twonly a try, please keep in mind that it is still in its ### Currently - Focus on user-friendliness so that people enjoy using the app - - User discovery without a phone number - Passwordless recovery without a phone number - Implementation of features so that Snapchat can actually be replaced - E2EE cloud backup of memories diff --git a/lib/core/bridge/callbacks/user_discovery.dart b/lib/core/bridge/callbacks/user_discovery.dart new file mode 100644 index 00000000..569a0013 --- /dev/null +++ b/lib/core/bridge/callbacks/user_discovery.dart @@ -0,0 +1,173 @@ +// 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, unnecessary_import + +import '../../bridge.dart'; +import '../../frb_generated.dart'; +import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; + +// 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` + +class UserDiscoveryStoreFlutter { + const UserDiscoveryStoreFlutter(); + + Future getAnnouncedUserByPublicId({ + required PlatformInt64 publicId, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetAnnouncedUserByPublicId( + that: this, + publicId: publicId, + ); + + Future getConfig() => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetConfig( + that: this, + ); + + Future getContactPromotion({ + required PlatformInt64 contactId, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetContactPromotion( + that: this, + contactId: contactId, + ); + + Future getContactVersion({ + required PlatformInt64 contactId, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetContactVersion( + that: this, + contactId: contactId, + ); + + Future> getOtherPromotionsByPublicId({ + required PlatformInt64 publicId, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetOtherPromotionsByPublicId( + that: this, + publicId: publicId, + ); + + Future> getOwnPromotionsAfterVersion({ + required int version, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetOwnPromotionsAfterVersion( + that: this, + version: version, + ); + + Future getShareForContact({ + required PlatformInt64 contactId, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetShareForContact( + that: this, + contactId: contactId, + ); + + Future pushNewUserRelation({ + required PlatformInt64 fromContactId, + required AnnouncedUser announcedUser, + PlatformInt64? publicKeyVerifiedTimestamp, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterPushNewUserRelation( + that: this, + fromContactId: fromContactId, + announcedUser: announcedUser, + publicKeyVerifiedTimestamp: publicKeyVerifiedTimestamp, + ); + + Future pushOwnPromotionAndClearOldVersion({ + required PlatformInt64 contactId, + required int version, + required List promotion, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterPushOwnPromotionAndClearOldVersion( + that: this, + contactId: contactId, + version: version, + promotion: promotion, + ); + + Future setContactVersion({ + required PlatformInt64 contactId, + required List update, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterSetContactVersion( + that: this, + contactId: contactId, + update: update, + ); + + Future setShares({required List shares}) => RustLib + .instance + .api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterSetShares( + that: this, + shares: shares, + ); + + Future storeOtherPromotion({ + required OtherPromotion promotion, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterStoreOtherPromotion( + that: this, + promotion: promotion, + ); + + Future updateConfig({required String update}) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterUpdateConfig( + that: this, + update: update, + ); + + @override + int get hashCode => 0; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is UserDiscoveryStoreFlutter && runtimeType == other.runtimeType; +} + +class UserDiscoveryUtilsFlutter { + const UserDiscoveryUtilsFlutter(); + + Future signData({required List inputData}) => RustLib + .instance + .api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterSignData( + that: this, + inputData: inputData, + ); + + Future verifySignature({ + required List inputData, + required List pubkey, + required List signature, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterVerifySignature( + that: this, + inputData: inputData, + pubkey: pubkey, + signature: signature, + ); + + Future verifyStoredPubkey({ + required PlatformInt64 fromContactId, + required List pubkey, + }) => RustLib.instance.api + .crateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterVerifyStoredPubkey( + that: this, + fromContactId: fromContactId, + pubkey: pubkey, + ); + + @override + int get hashCode => 0; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is UserDiscoveryUtilsFlutter && runtimeType == other.runtimeType; +} diff --git a/lib/core/bridge/wrapper.dart b/lib/core/bridge/wrapper.dart new file mode 100644 index 00000000..a81cf112 --- /dev/null +++ b/lib/core/bridge/wrapper.dart @@ -0,0 +1,37 @@ +// 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, unnecessary_import + +import '../frb_generated.dart'; +import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; + +class RustUtils { + const RustUtils(); + + static Future> generateShares({ + required List secret, + required int total, + required int threshold, + }) => RustLib.instance.api.crateBridgeWrapperRustUtilsGenerateShares( + secret: secret, + total: total, + threshold: threshold, + ); + + static Future recoverSecret({ + required List shares, + required int threshold, + }) => RustLib.instance.api.crateBridgeWrapperRustUtilsRecoverSecret( + shares: shares, + threshold: threshold, + ); + + @override + int get hashCode => 0; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is RustUtils && runtimeType == other.runtimeType; +} diff --git a/lib/core/bridge/wrapper/key_manager.dart b/lib/core/bridge/wrapper/key_manager.dart index 46c57e90..a3517edc 100644 --- a/lib/core/bridge/wrapper/key_manager.dart +++ b/lib/core/bridge/wrapper/key_manager.dart @@ -53,6 +53,10 @@ class RustKeyManager { signedPreKeyId: signedPreKeyId, ); + /// Serialize the key_manager. Needed for the passwordless_recovery feature. + static Future serialize() => RustLib.instance.api + .crateBridgeWrapperKeyManagerRustKeyManagerSerialize(); + static Future setUserId({required PlatformInt64 userId}) => RustLib .instance .api diff --git a/lib/core/frb_generated.dart b/lib/core/frb_generated.dart index 8570e08f..376bc9ad 100644 --- a/lib/core/frb_generated.dart +++ b/lib/core/frb_generated.dart @@ -5,6 +5,8 @@ import 'bridge.dart'; import 'bridge/callbacks.dart'; +import 'bridge/callbacks/user_discovery.dart'; +import 'bridge/wrapper.dart'; import 'bridge/wrapper/backup.dart'; import 'bridge/wrapper/key_manager.dart'; import 'bridge/wrapper/user_discovery.dart'; @@ -74,7 +76,7 @@ class RustLib extends BaseEntrypoint { String get codegenVersion => '2.12.0'; @override - int get rustContentHash => -1867463121; + int get rustContentHash => -508562557; static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig( @@ -230,6 +232,8 @@ abstract class RustLibApi extends BaseApi { required PlatformInt64 signedPreKeyId, }); + Future crateBridgeWrapperKeyManagerRustKeyManagerSerialize(); + Future crateBridgeWrapperKeyManagerRustKeyManagerSetUserId({ required PlatformInt64 userId, }); @@ -238,6 +242,120 @@ abstract class RustLibApi extends BaseApi { required PlatformInt64 signedPreKeyId, required List record, }); + + Future> crateBridgeWrapperRustUtilsGenerateShares({ + required List secret, + required int total, + required int threshold, + }); + + Future crateBridgeWrapperRustUtilsRecoverSecret({ + required List shares, + required int threshold, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetAnnouncedUserByPublicId({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 publicId, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetConfig({ + required UserDiscoveryStoreFlutter that, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetContactPromotion({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 contactId, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetContactVersion({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 contactId, + }); + + Future> + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetOtherPromotionsByPublicId({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 publicId, + }); + + Future> + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetOwnPromotionsAfterVersion({ + required UserDiscoveryStoreFlutter that, + required int version, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetShareForContact({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 contactId, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterPushNewUserRelation({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 fromContactId, + required AnnouncedUser announcedUser, + PlatformInt64? publicKeyVerifiedTimestamp, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterPushOwnPromotionAndClearOldVersion({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 contactId, + required int version, + required List promotion, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterSetContactVersion({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 contactId, + required List update, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterSetShares({ + required UserDiscoveryStoreFlutter that, + required List shares, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterStoreOtherPromotion({ + required UserDiscoveryStoreFlutter that, + required OtherPromotion promotion, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterUpdateConfig({ + required UserDiscoveryStoreFlutter that, + required String update, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterSignData({ + required UserDiscoveryUtilsFlutter that, + required List inputData, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterVerifySignature({ + required UserDiscoveryUtilsFlutter that, + required List inputData, + required List pubkey, + required List signature, + }); + + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterVerifyStoredPubkey({ + required UserDiscoveryUtilsFlutter that, + required PlatformInt64 fromContactId, + required List pubkey, + }); } class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { @@ -1302,6 +1420,38 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["signedPreKeyId"], ); + @override + Future crateBridgeWrapperKeyManagerRustKeyManagerSerialize() { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 26, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_list_prim_u_8_strict, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeWrapperKeyManagerRustKeyManagerSerializeConstMeta, + argValues: [], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeWrapperKeyManagerRustKeyManagerSerializeConstMeta => + const TaskConstMeta( + debugName: "rust_key_manager_serialize", + argNames: [], + ); + @override Future crateBridgeWrapperKeyManagerRustKeyManagerSetUserId({ required PlatformInt64 userId, @@ -1314,7 +1464,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 26, + funcId: 27, port: port_, ); }, @@ -1351,7 +1501,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 27, + funcId: 28, port: port_, ); }, @@ -1374,6 +1524,717 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["signedPreKeyId", "record"], ); + @override + Future> crateBridgeWrapperRustUtilsGenerateShares({ + required List secret, + required int total, + required int threshold, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_list_prim_u_8_loose(secret, serializer); + sse_encode_u_8(total, serializer); + sse_encode_u_8(threshold, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 29, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_list_list_prim_u_8_strict, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: kCrateBridgeWrapperRustUtilsGenerateSharesConstMeta, + argValues: [secret, total, threshold], + apiImpl: this, + ), + ); + } + + TaskConstMeta get kCrateBridgeWrapperRustUtilsGenerateSharesConstMeta => + const TaskConstMeta( + debugName: "rust_utils_generate_shares", + argNames: ["secret", "total", "threshold"], + ); + + @override + Future crateBridgeWrapperRustUtilsRecoverSecret({ + required List shares, + required int threshold, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_list_list_prim_u_8_strict(shares, serializer); + sse_encode_u_8(threshold, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 30, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_list_prim_u_8_strict, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: kCrateBridgeWrapperRustUtilsRecoverSecretConstMeta, + argValues: [shares, threshold], + apiImpl: this, + ), + ); + } + + TaskConstMeta get kCrateBridgeWrapperRustUtilsRecoverSecretConstMeta => + const TaskConstMeta( + debugName: "rust_utils_recover_secret", + argNames: ["shares", "threshold"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetAnnouncedUserByPublicId({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 publicId, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_i_64(publicId, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 31, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_opt_box_autoadd_announced_user, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetAnnouncedUserByPublicIdConstMeta, + argValues: [that, publicId], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetAnnouncedUserByPublicIdConstMeta => + const TaskConstMeta( + debugName: + "user_discovery_store_flutter_get_announced_user_by_public_id", + argNames: ["that", "publicId"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetConfig({ + required UserDiscoveryStoreFlutter that, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 32, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_String, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetConfigConstMeta, + argValues: [that], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetConfigConstMeta => + const TaskConstMeta( + debugName: "user_discovery_store_flutter_get_config", + argNames: ["that"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetContactPromotion({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 contactId, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_i_64(contactId, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 33, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_opt_list_prim_u_8_strict, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetContactPromotionConstMeta, + argValues: [that, contactId], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetContactPromotionConstMeta => + const TaskConstMeta( + debugName: "user_discovery_store_flutter_get_contact_promotion", + argNames: ["that", "contactId"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetContactVersion({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 contactId, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_i_64(contactId, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 34, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_opt_list_prim_u_8_strict, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetContactVersionConstMeta, + argValues: [that, contactId], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetContactVersionConstMeta => + const TaskConstMeta( + debugName: "user_discovery_store_flutter_get_contact_version", + argNames: ["that", "contactId"], + ); + + @override + Future> + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetOtherPromotionsByPublicId({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 publicId, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_i_64(publicId, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 35, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_list_other_promotion, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetOtherPromotionsByPublicIdConstMeta, + argValues: [that, publicId], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetOtherPromotionsByPublicIdConstMeta => + const TaskConstMeta( + debugName: + "user_discovery_store_flutter_get_other_promotions_by_public_id", + argNames: ["that", "publicId"], + ); + + @override + Future> + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetOwnPromotionsAfterVersion({ + required UserDiscoveryStoreFlutter that, + required int version, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_u_32(version, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 36, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_list_list_prim_u_8_strict, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetOwnPromotionsAfterVersionConstMeta, + argValues: [that, version], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetOwnPromotionsAfterVersionConstMeta => + const TaskConstMeta( + debugName: + "user_discovery_store_flutter_get_own_promotions_after_version", + argNames: ["that", "version"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetShareForContact({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 contactId, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_i_64(contactId, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 37, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_list_prim_u_8_strict, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetShareForContactConstMeta, + argValues: [that, contactId], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterGetShareForContactConstMeta => + const TaskConstMeta( + debugName: "user_discovery_store_flutter_get_share_for_contact", + argNames: ["that", "contactId"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterPushNewUserRelation({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 fromContactId, + required AnnouncedUser announcedUser, + PlatformInt64? publicKeyVerifiedTimestamp, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_i_64(fromContactId, serializer); + sse_encode_box_autoadd_announced_user(announcedUser, serializer); + sse_encode_opt_box_autoadd_i_64( + publicKeyVerifiedTimestamp, + serializer, + ); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 38, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterPushNewUserRelationConstMeta, + argValues: [ + that, + fromContactId, + announcedUser, + publicKeyVerifiedTimestamp, + ], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterPushNewUserRelationConstMeta => + const TaskConstMeta( + debugName: "user_discovery_store_flutter_push_new_user_relation", + argNames: [ + "that", + "fromContactId", + "announcedUser", + "publicKeyVerifiedTimestamp", + ], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterPushOwnPromotionAndClearOldVersion({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 contactId, + required int version, + required List promotion, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_i_64(contactId, serializer); + sse_encode_u_32(version, serializer); + sse_encode_list_prim_u_8_loose(promotion, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 39, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterPushOwnPromotionAndClearOldVersionConstMeta, + argValues: [that, contactId, version, promotion], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterPushOwnPromotionAndClearOldVersionConstMeta => + const TaskConstMeta( + debugName: + "user_discovery_store_flutter_push_own_promotion_and_clear_old_version", + argNames: ["that", "contactId", "version", "promotion"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterSetContactVersion({ + required UserDiscoveryStoreFlutter that, + required PlatformInt64 contactId, + required List update, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_i_64(contactId, serializer); + sse_encode_list_prim_u_8_loose(update, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 40, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterSetContactVersionConstMeta, + argValues: [that, contactId, update], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterSetContactVersionConstMeta => + const TaskConstMeta( + debugName: "user_discovery_store_flutter_set_contact_version", + argNames: ["that", "contactId", "update"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterSetShares({ + required UserDiscoveryStoreFlutter that, + required List shares, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_list_list_prim_u_8_strict(shares, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 41, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterSetSharesConstMeta, + argValues: [that, shares], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterSetSharesConstMeta => + const TaskConstMeta( + debugName: "user_discovery_store_flutter_set_shares", + argNames: ["that", "shares"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterStoreOtherPromotion({ + required UserDiscoveryStoreFlutter that, + required OtherPromotion promotion, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_box_autoadd_other_promotion(promotion, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 42, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterStoreOtherPromotionConstMeta, + argValues: [that, promotion], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterStoreOtherPromotionConstMeta => + const TaskConstMeta( + debugName: "user_discovery_store_flutter_store_other_promotion", + argNames: ["that", "promotion"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterUpdateConfig({ + required UserDiscoveryStoreFlutter that, + required String update, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_store_flutter(that, serializer); + sse_encode_String(update, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 43, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterUpdateConfigConstMeta, + argValues: [that, update], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryStoreFlutterUpdateConfigConstMeta => + const TaskConstMeta( + debugName: "user_discovery_store_flutter_update_config", + argNames: ["that", "update"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterSignData({ + required UserDiscoveryUtilsFlutter that, + required List inputData, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_utils_flutter(that, serializer); + sse_encode_list_prim_u_8_loose(inputData, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 44, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_list_prim_u_8_strict, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterSignDataConstMeta, + argValues: [that, inputData], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterSignDataConstMeta => + const TaskConstMeta( + debugName: "user_discovery_utils_flutter_sign_data", + argNames: ["that", "inputData"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterVerifySignature({ + required UserDiscoveryUtilsFlutter that, + required List inputData, + required List pubkey, + required List signature, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_utils_flutter(that, serializer); + sse_encode_list_prim_u_8_loose(inputData, serializer); + sse_encode_list_prim_u_8_loose(pubkey, serializer); + sse_encode_list_prim_u_8_loose(signature, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 45, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_bool, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterVerifySignatureConstMeta, + argValues: [that, inputData, pubkey, signature], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterVerifySignatureConstMeta => + const TaskConstMeta( + debugName: "user_discovery_utils_flutter_verify_signature", + argNames: ["that", "inputData", "pubkey", "signature"], + ); + + @override + Future + crateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterVerifyStoredPubkey({ + required UserDiscoveryUtilsFlutter that, + required PlatformInt64 fromContactId, + required List pubkey, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_box_autoadd_user_discovery_utils_flutter(that, serializer); + sse_encode_i_64(fromContactId, serializer); + sse_encode_list_prim_u_8_loose(pubkey, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 46, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_bool, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: + kCrateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterVerifyStoredPubkeyConstMeta, + argValues: [that, fromContactId, pubkey], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateBridgeCallbacksUserDiscoveryUserDiscoveryUtilsFlutterVerifyStoredPubkeyConstMeta => + const TaskConstMeta( + debugName: "user_discovery_utils_flutter_verify_stored_pubkey", + argNames: ["that", "fromContactId", "pubkey"], + ); + Future Function( int, ) @@ -2002,6 +2863,28 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return dco_decode_init_config(raw); } + @protected + OtherPromotion dco_decode_box_autoadd_other_promotion(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return dco_decode_other_promotion(raw); + } + + @protected + UserDiscoveryStoreFlutter dco_decode_box_autoadd_user_discovery_store_flutter( + dynamic raw, + ) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return dco_decode_user_discovery_store_flutter(raw); + } + + @protected + UserDiscoveryUtilsFlutter dco_decode_box_autoadd_user_discovery_utils_flutter( + dynamic raw, + ) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return dco_decode_user_discovery_utils_flutter(raw); + } + @protected FlutterUserDiscovery dco_decode_flutter_user_discovery(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -2190,6 +3073,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return RustKeyManager(); } + @protected + RustUtils dco_decode_rust_utils(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + final arr = raw as List; + if (arr.length != 0) + throw Exception('unexpected arr length: expect 0 but see ${arr.length}'); + return RustUtils(); + } + @protected int dco_decode_u_32(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -2214,6 +3106,28 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return; } + @protected + UserDiscoveryStoreFlutter dco_decode_user_discovery_store_flutter( + dynamic raw, + ) { + // Codec=Dco (DartCObject based), see doc to use other codecs + final arr = raw as List; + if (arr.length != 0) + throw Exception('unexpected arr length: expect 0 but see ${arr.length}'); + return UserDiscoveryStoreFlutter(); + } + + @protected + UserDiscoveryUtilsFlutter dco_decode_user_discovery_utils_flutter( + dynamic raw, + ) { + // Codec=Dco (DartCObject based), see doc to use other codecs + final arr = raw as List; + if (arr.length != 0) + throw Exception('unexpected arr length: expect 0 but see ${arr.length}'); + return UserDiscoveryUtilsFlutter(); + } + @protected BigInt dco_decode_usize(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -2318,6 +3232,30 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return (sse_decode_init_config(deserializer)); } + @protected + OtherPromotion sse_decode_box_autoadd_other_promotion( + SseDeserializer deserializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + return (sse_decode_other_promotion(deserializer)); + } + + @protected + UserDiscoveryStoreFlutter sse_decode_box_autoadd_user_discovery_store_flutter( + SseDeserializer deserializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + return (sse_decode_user_discovery_store_flutter(deserializer)); + } + + @protected + UserDiscoveryUtilsFlutter sse_decode_box_autoadd_user_discovery_utils_flutter( + SseDeserializer deserializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + return (sse_decode_user_discovery_utils_flutter(deserializer)); + } + @protected FlutterUserDiscovery sse_decode_flutter_user_discovery( SseDeserializer deserializer, @@ -2548,6 +3486,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return RustKeyManager(); } + @protected + RustUtils sse_decode_rust_utils(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return RustUtils(); + } + @protected int sse_decode_u_32(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -2572,6 +3516,22 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { // Codec=Sse (Serialization based), see doc to use other codecs } + @protected + UserDiscoveryStoreFlutter sse_decode_user_discovery_store_flutter( + SseDeserializer deserializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + return UserDiscoveryStoreFlutter(); + } + + @protected + UserDiscoveryUtilsFlutter sse_decode_user_discovery_utils_flutter( + SseDeserializer deserializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + return UserDiscoveryUtilsFlutter(); + } + @protected BigInt sse_decode_usize(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -2877,6 +3837,33 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_init_config(self, serializer); } + @protected + void sse_encode_box_autoadd_other_promotion( + OtherPromotion self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_other_promotion(self, serializer); + } + + @protected + void sse_encode_box_autoadd_user_discovery_store_flutter( + UserDiscoveryStoreFlutter self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_user_discovery_store_flutter(self, serializer); + } + + @protected + void sse_encode_box_autoadd_user_discovery_utils_flutter( + UserDiscoveryUtilsFlutter self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_user_discovery_utils_flutter(self, serializer); + } + @protected void sse_encode_flutter_user_discovery( FlutterUserDiscovery self, @@ -3108,6 +4095,11 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { // Codec=Sse (Serialization based), see doc to use other codecs } + @protected + void sse_encode_rust_utils(RustUtils self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + } + @protected void sse_encode_u_32(int self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -3131,6 +4123,22 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { // Codec=Sse (Serialization based), see doc to use other codecs } + @protected + void sse_encode_user_discovery_store_flutter( + UserDiscoveryStoreFlutter self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + } + + @protected + void sse_encode_user_discovery_utils_flutter( + UserDiscoveryUtilsFlutter self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + } + @protected void sse_encode_usize(BigInt 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 938d45c5..6b1600a0 100644 --- a/lib/core/frb_generated.io.dart +++ b/lib/core/frb_generated.io.dart @@ -5,6 +5,8 @@ import 'bridge.dart'; import 'bridge/callbacks.dart'; +import 'bridge/callbacks/user_discovery.dart'; +import 'bridge/wrapper.dart'; import 'bridge/wrapper/backup.dart'; import 'bridge/wrapper/key_manager.dart'; import 'bridge/wrapper/user_discovery.dart'; @@ -134,6 +136,19 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected InitConfig dco_decode_box_autoadd_init_config(dynamic raw); + @protected + OtherPromotion dco_decode_box_autoadd_other_promotion(dynamic raw); + + @protected + UserDiscoveryStoreFlutter dco_decode_box_autoadd_user_discovery_store_flutter( + dynamic raw, + ); + + @protected + UserDiscoveryUtilsFlutter dco_decode_box_autoadd_user_discovery_utils_flutter( + dynamic raw, + ); + @protected FlutterUserDiscovery dco_decode_flutter_user_discovery(dynamic raw); @@ -205,6 +220,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected RustKeyManager dco_decode_rust_key_manager(dynamic raw); + @protected + RustUtils dco_decode_rust_utils(dynamic raw); + @protected int dco_decode_u_32(dynamic raw); @@ -217,6 +235,16 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void dco_decode_unit(dynamic raw); + @protected + UserDiscoveryStoreFlutter dco_decode_user_discovery_store_flutter( + dynamic raw, + ); + + @protected + UserDiscoveryUtilsFlutter dco_decode_user_discovery_utils_flutter( + dynamic raw, + ); + @protected BigInt dco_decode_usize(dynamic raw); @@ -266,6 +294,21 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected InitConfig sse_decode_box_autoadd_init_config(SseDeserializer deserializer); + @protected + OtherPromotion sse_decode_box_autoadd_other_promotion( + SseDeserializer deserializer, + ); + + @protected + UserDiscoveryStoreFlutter sse_decode_box_autoadd_user_discovery_store_flutter( + SseDeserializer deserializer, + ); + + @protected + UserDiscoveryUtilsFlutter sse_decode_box_autoadd_user_discovery_utils_flutter( + SseDeserializer deserializer, + ); + @protected FlutterUserDiscovery sse_decode_flutter_user_discovery( SseDeserializer deserializer, @@ -357,6 +400,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected RustKeyManager sse_decode_rust_key_manager(SseDeserializer deserializer); + @protected + RustUtils sse_decode_rust_utils(SseDeserializer deserializer); + @protected int sse_decode_u_32(SseDeserializer deserializer); @@ -369,6 +415,16 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_decode_unit(SseDeserializer deserializer); + @protected + UserDiscoveryStoreFlutter sse_decode_user_discovery_store_flutter( + SseDeserializer deserializer, + ); + + @protected + UserDiscoveryUtilsFlutter sse_decode_user_discovery_utils_flutter( + SseDeserializer deserializer, + ); + @protected BigInt sse_decode_usize(SseDeserializer deserializer); @@ -517,6 +573,24 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void sse_encode_box_autoadd_other_promotion( + OtherPromotion self, + SseSerializer serializer, + ); + + @protected + void sse_encode_box_autoadd_user_discovery_store_flutter( + UserDiscoveryStoreFlutter self, + SseSerializer serializer, + ); + + @protected + void sse_encode_box_autoadd_user_discovery_utils_flutter( + UserDiscoveryUtilsFlutter self, + SseSerializer serializer, + ); + @protected void sse_encode_flutter_user_discovery( FlutterUserDiscovery self, @@ -634,6 +708,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void sse_encode_rust_utils(RustUtils self, SseSerializer serializer); + @protected void sse_encode_u_32(int self, SseSerializer serializer); @@ -646,6 +723,18 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_unit(void self, SseSerializer serializer); + @protected + void sse_encode_user_discovery_store_flutter( + UserDiscoveryStoreFlutter self, + SseSerializer serializer, + ); + + @protected + void sse_encode_user_discovery_utils_flutter( + UserDiscoveryUtilsFlutter self, + SseSerializer serializer, + ); + @protected void sse_encode_usize(BigInt self, SseSerializer serializer); diff --git a/lib/core/frb_generated.web.dart b/lib/core/frb_generated.web.dart index 23c61b25..ed0ca4ee 100644 --- a/lib/core/frb_generated.web.dart +++ b/lib/core/frb_generated.web.dart @@ -8,6 +8,8 @@ import 'bridge.dart'; import 'bridge/callbacks.dart'; +import 'bridge/callbacks/user_discovery.dart'; +import 'bridge/wrapper.dart'; import 'bridge/wrapper/backup.dart'; import 'bridge/wrapper/key_manager.dart'; import 'bridge/wrapper/user_discovery.dart'; @@ -136,6 +138,19 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected InitConfig dco_decode_box_autoadd_init_config(dynamic raw); + @protected + OtherPromotion dco_decode_box_autoadd_other_promotion(dynamic raw); + + @protected + UserDiscoveryStoreFlutter dco_decode_box_autoadd_user_discovery_store_flutter( + dynamic raw, + ); + + @protected + UserDiscoveryUtilsFlutter dco_decode_box_autoadd_user_discovery_utils_flutter( + dynamic raw, + ); + @protected FlutterUserDiscovery dco_decode_flutter_user_discovery(dynamic raw); @@ -207,6 +222,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected RustKeyManager dco_decode_rust_key_manager(dynamic raw); + @protected + RustUtils dco_decode_rust_utils(dynamic raw); + @protected int dco_decode_u_32(dynamic raw); @@ -219,6 +237,16 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void dco_decode_unit(dynamic raw); + @protected + UserDiscoveryStoreFlutter dco_decode_user_discovery_store_flutter( + dynamic raw, + ); + + @protected + UserDiscoveryUtilsFlutter dco_decode_user_discovery_utils_flutter( + dynamic raw, + ); + @protected BigInt dco_decode_usize(dynamic raw); @@ -268,6 +296,21 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected InitConfig sse_decode_box_autoadd_init_config(SseDeserializer deserializer); + @protected + OtherPromotion sse_decode_box_autoadd_other_promotion( + SseDeserializer deserializer, + ); + + @protected + UserDiscoveryStoreFlutter sse_decode_box_autoadd_user_discovery_store_flutter( + SseDeserializer deserializer, + ); + + @protected + UserDiscoveryUtilsFlutter sse_decode_box_autoadd_user_discovery_utils_flutter( + SseDeserializer deserializer, + ); + @protected FlutterUserDiscovery sse_decode_flutter_user_discovery( SseDeserializer deserializer, @@ -359,6 +402,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected RustKeyManager sse_decode_rust_key_manager(SseDeserializer deserializer); + @protected + RustUtils sse_decode_rust_utils(SseDeserializer deserializer); + @protected int sse_decode_u_32(SseDeserializer deserializer); @@ -371,6 +417,16 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_decode_unit(SseDeserializer deserializer); + @protected + UserDiscoveryStoreFlutter sse_decode_user_discovery_store_flutter( + SseDeserializer deserializer, + ); + + @protected + UserDiscoveryUtilsFlutter sse_decode_user_discovery_utils_flutter( + SseDeserializer deserializer, + ); + @protected BigInt sse_decode_usize(SseDeserializer deserializer); @@ -519,6 +575,24 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void sse_encode_box_autoadd_other_promotion( + OtherPromotion self, + SseSerializer serializer, + ); + + @protected + void sse_encode_box_autoadd_user_discovery_store_flutter( + UserDiscoveryStoreFlutter self, + SseSerializer serializer, + ); + + @protected + void sse_encode_box_autoadd_user_discovery_utils_flutter( + UserDiscoveryUtilsFlutter self, + SseSerializer serializer, + ); + @protected void sse_encode_flutter_user_discovery( FlutterUserDiscovery self, @@ -636,6 +710,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void sse_encode_rust_utils(RustUtils self, SseSerializer serializer); + @protected void sse_encode_u_32(int self, SseSerializer serializer); @@ -648,6 +725,18 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_unit(void self, SseSerializer serializer); + @protected + void sse_encode_user_discovery_store_flutter( + UserDiscoveryStoreFlutter self, + SseSerializer serializer, + ); + + @protected + void sse_encode_user_discovery_utils_flutter( + UserDiscoveryUtilsFlutter self, + SseSerializer serializer, + ); + @protected void sse_encode_usize(BigInt self, SseSerializer serializer); diff --git a/lib/src/database/schemas/twonly_db/drift_schema_v21.json b/lib/src/database/schemas/twonly_db/drift_schema_v21.json new file mode 100644 index 00000000..8684872c --- /dev/null +++ b/lib/src/database/schemas/twonly_db/drift_schema_v21.json @@ -0,0 +1,3127 @@ +{ + "_meta": { + "description": "This file contains a serialized version of schema entities for drift.", + "version": "1.3.0" + }, + "options": { + "store_date_time_values_as_text": false + }, + "entities": [ + { + "id": 0, + "references": [], + "type": "table", + "data": { + "name": "contacts", + "was_declared_in_moor": false, + "columns": [ + { + "name": "user_id", + "getter_name": "userId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "username", + "getter_name": "username", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "display_name", + "getter_name": "displayName", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "nick_name", + "getter_name": "nickName", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "avatar_svg_compressed", + "getter_name": "avatarSvgCompressed", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "sender_profile_counter", + "getter_name": "senderProfileCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "accepted", + "getter_name": "accepted", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"accepted\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"accepted\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "deleted_by_user", + "getter_name": "deletedByUser", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"deleted_by_user\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"deleted_by_user\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "requested", + "getter_name": "requested", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"requested\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"requested\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "blocked", + "getter_name": "blocked", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"blocked\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"blocked\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "verified", + "getter_name": "verified", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"verified\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"verified\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "account_deleted", + "getter_name": "accountDeleted", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"account_deleted\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"account_deleted\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "user_discovery_version", + "getter_name": "userDiscoveryVersion", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "user_discovery_excluded", + "getter_name": "userDiscoveryExcluded", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"user_discovery_excluded\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"user_discovery_excluded\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "user_discovery_manual_approved", + "getter_name": "userDiscoveryManualApproved", + "moor_type": "bool", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "CHECK (\"user_discovery_manual_approved\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"user_discovery_manual_approved\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "recovery_is_trusted_friend", + "getter_name": "recoveryIsTrustedFriend", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"recovery_is_trusted_friend\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"recovery_is_trusted_friend\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "recovery_last_heartbeat", + "getter_name": "recoveryLastHeartbeat", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "recovery_secret_share", + "getter_name": "recoverySecretShare", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "recovery_contacts_secret_share", + "getter_name": "recoveryContactsSecretShare", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "recovery_contacts_last_heartbeat", + "getter_name": "recoveryContactsLastHeartbeat", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "ask_for_friend_promotions", + "getter_name": "askForFriendPromotions", + "moor_type": "bool", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "CHECK (\"ask_for_friend_promotions\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"ask_for_friend_promotions\" IN (0, 1))" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "media_send_counter", + "getter_name": "mediaSendCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "media_received_counter", + "getter_name": "mediaReceivedCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "user_id" + ] + } + }, + { + "id": 1, + "references": [], + "type": "table", + "data": { + "name": "groups", + "was_declared_in_moor": false, + "columns": [ + { + "name": "group_id", + "getter_name": "groupId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "is_group_admin", + "getter_name": "isGroupAdmin", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_group_admin\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_group_admin\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "is_direct_chat", + "getter_name": "isDirectChat", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_direct_chat\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_direct_chat\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "pinned", + "getter_name": "pinned", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"pinned\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"pinned\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "archived", + "getter_name": "archived", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"archived\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"archived\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "joined_group", + "getter_name": "joinedGroup", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"joined_group\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"joined_group\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "left_group", + "getter_name": "leftGroup", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"left_group\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"left_group\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "deleted_content", + "getter_name": "deletedContent", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"deleted_content\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"deleted_content\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "state_version_id", + "getter_name": "stateVersionId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "state_encryption_key", + "getter_name": "stateEncryptionKey", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "my_group_private_key", + "getter_name": "myGroupPrivateKey", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "group_name", + "getter_name": "groupName", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "draft_message", + "getter_name": "draftMessage", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "total_media_counter", + "getter_name": "totalMediaCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "also_best_friend", + "getter_name": "alsoBestFriend", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"also_best_friend\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"also_best_friend\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "delete_messages_after_milliseconds", + "getter_name": "deleteMessagesAfterMilliseconds", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('86400000')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_message_send", + "getter_name": "lastMessageSend", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_message_received", + "getter_name": "lastMessageReceived", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_flame_counter_change", + "getter_name": "lastFlameCounterChange", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_flame_sync", + "getter_name": "lastFlameSync", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "flame_counter", + "getter_name": "flameCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "max_flame_counter", + "getter_name": "maxFlameCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "max_flame_counter_from", + "getter_name": "maxFlameCounterFrom", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_message_exchange", + "getter_name": "lastMessageExchange", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "group_id" + ] + } + }, + { + "id": 2, + "references": [], + "type": "table", + "data": { + "name": "media_files", + "was_declared_in_moor": false, + "columns": [ + { + "name": "media_id", + "getter_name": "mediaId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "type", + "getter_name": "type", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(MediaType.values)", + "dart_type_name": "MediaType" + } + }, + { + "name": "upload_state", + "getter_name": "uploadState", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(UploadState.values)", + "dart_type_name": "UploadState" + } + }, + { + "name": "download_state", + "getter_name": "downloadState", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(DownloadState.values)", + "dart_type_name": "DownloadState" + } + }, + { + "name": "requires_authentication", + "getter_name": "requiresAuthentication", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"requires_authentication\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"requires_authentication\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "stored", + "getter_name": "stored", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"stored\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"stored\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "is_draft_media", + "getter_name": "isDraftMedia", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_draft_media\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_draft_media\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "is_favorite", + "getter_name": "isFavorite", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_favorite\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_favorite\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "has_crop_analyzed", + "getter_name": "hasCropAnalyzed", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"has_crop_analyzed\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"has_crop_analyzed\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "pre_progressing_process", + "getter_name": "preProgressingProcess", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "reupload_requested_by", + "getter_name": "reuploadRequestedBy", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "IntListTypeConverter()", + "dart_type_name": "List" + } + }, + { + "name": "display_limit_in_milliseconds", + "getter_name": "displayLimitInMilliseconds", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "remove_audio", + "getter_name": "removeAudio", + "moor_type": "bool", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "CHECK (\"remove_audio\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"remove_audio\" IN (0, 1))" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "download_token", + "getter_name": "downloadToken", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "encryption_key", + "getter_name": "encryptionKey", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "encryption_mac", + "getter_name": "encryptionMac", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "encryption_nonce", + "getter_name": "encryptionNonce", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "stored_file_hash", + "getter_name": "storedFileHash", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "has_thumbnail", + "getter_name": "hasThumbnail", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"has_thumbnail\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"has_thumbnail\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "size_in_bytes", + "getter_name": "sizeInBytes", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at_month", + "getter_name": "createdAtMonth", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "media_id" + ] + } + }, + { + "id": 3, + "references": [ + 1, + 0, + 2 + ], + "type": "table", + "data": { + "name": "messages", + "was_declared_in_moor": false, + "columns": [ + { + "name": "group_id", + "getter_name": "groupId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "groups", + "column": "group_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "message_id", + "getter_name": "messageId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "sender_id", + "getter_name": "senderId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id)", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id)" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": null + } + } + ] + }, + { + "name": "type", + "getter_name": "type", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "content", + "getter_name": "content", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "media_id", + "getter_name": "mediaId", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES media_files (media_id) ON DELETE SET NULL", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES media_files (media_id) ON DELETE SET NULL" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "media_files", + "column": "media_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "setNull" + } + } + ] + }, + { + "name": "additional_message_data", + "getter_name": "additionalMessageData", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "media_stored", + "getter_name": "mediaStored", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"media_stored\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"media_stored\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "media_reopened", + "getter_name": "mediaReopened", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"media_reopened\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"media_reopened\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "download_token", + "getter_name": "downloadToken", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "quotes_message_id", + "getter_name": "quotesMessageId", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "is_deleted_from_sender", + "getter_name": "isDeletedFromSender", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_deleted_from_sender\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_deleted_from_sender\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "opened_at", + "getter_name": "openedAt", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "opened_by_all", + "getter_name": "openedByAll", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "modified_at", + "getter_name": "modifiedAt", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "ack_by_user", + "getter_name": "ackByUser", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "ack_by_server", + "getter_name": "ackByServer", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "message_id" + ] + } + }, + { + "id": 4, + "references": [ + 3, + 0 + ], + "type": "table", + "data": { + "name": "message_histories", + "was_declared_in_moor": false, + "columns": [ + { + "name": "id", + "getter_name": "id", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "message_id", + "getter_name": "messageId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES messages (message_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES messages (message_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "messages", + "column": "message_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "content", + "getter_name": "content", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 5, + "references": [ + 3, + 0 + ], + "type": "table", + "data": { + "name": "reactions", + "was_declared_in_moor": false, + "columns": [ + { + "name": "message_id", + "getter_name": "messageId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES messages (message_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES messages (message_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "messages", + "column": "message_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "emoji", + "getter_name": "emoji", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "sender_id", + "getter_name": "senderId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "message_id", + "sender_id", + "emoji" + ] + } + }, + { + "id": 6, + "references": [ + 1, + 0 + ], + "type": "table", + "data": { + "name": "group_members", + "was_declared_in_moor": false, + "columns": [ + { + "name": "group_id", + "getter_name": "groupId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "groups", + "column": "group_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id)", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id)" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": null + } + } + ] + }, + { + "name": "member_state", + "getter_name": "memberState", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(MemberState.values)", + "dart_type_name": "MemberState" + } + }, + { + "name": "group_public_key", + "getter_name": "groupPublicKey", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_chat_opened", + "getter_name": "lastChatOpened", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_type_indicator", + "getter_name": "lastTypeIndicator", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_message", + "getter_name": "lastMessage", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "group_id", + "contact_id" + ] + } + }, + { + "id": 7, + "references": [ + 0, + 3 + ], + "type": "table", + "data": { + "name": "receipts", + "was_declared_in_moor": false, + "columns": [ + { + "name": "receipt_id", + "getter_name": "receiptId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "message_id", + "getter_name": "messageId", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES messages (message_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES messages (message_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "messages", + "column": "message_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "message", + "getter_name": "message", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "contact_will_sends_receipt", + "getter_name": "contactWillSendsReceipt", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"contact_will_sends_receipt\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"contact_will_sends_receipt\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('1')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "will_be_retried_by_media_upload", + "getter_name": "willBeRetriedByMediaUpload", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"will_be_retried_by_media_upload\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"will_be_retried_by_media_upload\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "mark_for_retry", + "getter_name": "markForRetry", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "mark_for_retry_after_accepted", + "getter_name": "markForRetryAfterAccepted", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "ack_by_server_at", + "getter_name": "ackByServerAt", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "retry_count", + "getter_name": "retryCount", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_retry", + "getter_name": "lastRetry", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "receipt_id" + ] + } + }, + { + "id": 8, + "references": [], + "type": "table", + "data": { + "name": "received_receipts", + "was_declared_in_moor": false, + "columns": [ + { + "name": "receipt_id", + "getter_name": "receiptId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "receipt_id" + ] + } + }, + { + "id": 9, + "references": [], + "type": "table", + "data": { + "name": "signal_identity_key_stores", + "was_declared_in_moor": false, + "columns": [ + { + "name": "device_id", + "getter_name": "deviceId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "name", + "getter_name": "name", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "identity_key", + "getter_name": "identityKey", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "device_id", + "name" + ] + } + }, + { + "id": 10, + "references": [], + "type": "table", + "data": { + "name": "signal_pre_key_stores", + "was_declared_in_moor": false, + "columns": [ + { + "name": "pre_key_id", + "getter_name": "preKeyId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "pre_key", + "getter_name": "preKey", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "pre_key_id" + ] + } + }, + { + "id": 11, + "references": [], + "type": "table", + "data": { + "name": "signal_sender_key_stores", + "was_declared_in_moor": false, + "columns": [ + { + "name": "sender_key_name", + "getter_name": "senderKeyName", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "sender_key", + "getter_name": "senderKey", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "sender_key_name" + ] + } + }, + { + "id": 12, + "references": [], + "type": "table", + "data": { + "name": "signal_session_stores", + "was_declared_in_moor": false, + "columns": [ + { + "name": "device_id", + "getter_name": "deviceId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "name", + "getter_name": "name", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "session_record", + "getter_name": "sessionRecord", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "device_id", + "name" + ] + } + }, + { + "id": 13, + "references": [], + "type": "table", + "data": { + "name": "signal_signed_pre_key_stores", + "was_declared_in_moor": false, + "columns": [ + { + "name": "signed_pre_key_id", + "getter_name": "signedPreKeyId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "signed_pre_key", + "getter_name": "signedPreKey", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "signed_pre_key_id" + ] + } + }, + { + "id": 14, + "references": [ + 3, + 0 + ], + "type": "table", + "data": { + "name": "message_actions", + "was_declared_in_moor": false, + "columns": [ + { + "name": "message_id", + "getter_name": "messageId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES messages (message_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES messages (message_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "messages", + "column": "message_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "type", + "getter_name": "type", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(MessageActionType.values)", + "dart_type_name": "MessageActionType" + } + }, + { + "name": "action_at", + "getter_name": "actionAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "message_id", + "contact_id", + "type" + ] + } + }, + { + "id": 15, + "references": [ + 1, + 0 + ], + "type": "table", + "data": { + "name": "group_histories", + "was_declared_in_moor": false, + "columns": [ + { + "name": "group_history_id", + "getter_name": "groupHistoryId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "group_id", + "getter_name": "groupId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "groups", + "column": "group_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id)", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id)" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": null + } + } + ] + }, + { + "name": "affected_contact_id", + "getter_name": "affectedContactId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "old_group_name", + "getter_name": "oldGroupName", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "new_group_name", + "getter_name": "newGroupName", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "new_delete_messages_after_milliseconds", + "getter_name": "newDeleteMessagesAfterMilliseconds", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "type", + "getter_name": "type", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(GroupActionType.values)", + "dart_type_name": "GroupActionType" + } + }, + { + "name": "action_at", + "getter_name": "actionAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "group_history_id" + ] + } + }, + { + "id": 16, + "references": [ + 0 + ], + "type": "table", + "data": { + "name": "key_verifications", + "was_declared_in_moor": false, + "columns": [ + { + "name": "verification_id", + "getter_name": "verificationId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "type", + "getter_name": "type", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(VerificationType.values)", + "dart_type_name": "VerificationType" + } + }, + { + "name": "verified_by", + "getter_name": "verifiedBy", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 17, + "references": [], + "type": "table", + "data": { + "name": "verification_tokens", + "was_declared_in_moor": false, + "columns": [ + { + "name": "token_id", + "getter_name": "tokenId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "token", + "getter_name": "token", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 18, + "references": [], + "type": "table", + "data": { + "name": "user_discovery_announced_users", + "was_declared_in_moor": false, + "columns": [ + { + "name": "announced_user_id", + "getter_name": "announcedUserId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "announced_public_key", + "getter_name": "announcedPublicKey", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "public_id", + "getter_name": "publicId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "UNIQUE", + "dialectAwareDefaultConstraints": { + "sqlite": "UNIQUE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "unique" + ] + }, + { + "name": "username", + "getter_name": "username", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "was_shown_to_the_user", + "getter_name": "wasShownToTheUser", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"was_shown_to_the_user\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"was_shown_to_the_user\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "is_hidden", + "getter_name": "isHidden", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_hidden\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_hidden\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "was_asked_friends", + "getter_name": "wasAskedFriends", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"was_asked_friends\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"was_asked_friends\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "announced_user_id" + ] + } + }, + { + "id": 19, + "references": [ + 18, + 0 + ], + "type": "table", + "data": { + "name": "user_discovery_user_relations", + "was_declared_in_moor": false, + "columns": [ + { + "name": "announced_user_id", + "getter_name": "announcedUserId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES user_discovery_announced_users (announced_user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES user_discovery_announced_users (announced_user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "user_discovery_announced_users", + "column": "announced_user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "from_contact_id", + "getter_name": "fromContactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "public_key_verified_timestamp", + "getter_name": "publicKeyVerifiedTimestamp", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "announced_user_id", + "from_contact_id" + ] + } + }, + { + "id": 20, + "references": [ + 0 + ], + "type": "table", + "data": { + "name": "user_discovery_other_promotions", + "was_declared_in_moor": false, + "columns": [ + { + "name": "from_contact_id", + "getter_name": "fromContactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "promotion_id", + "getter_name": "promotionId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "public_id", + "getter_name": "publicId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "threshold", + "getter_name": "threshold", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "announcement_share", + "getter_name": "announcementShare", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "public_key_verified_timestamp", + "getter_name": "publicKeyVerifiedTimestamp", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "from_contact_id", + "public_id" + ] + } + }, + { + "id": 21, + "references": [ + 0 + ], + "type": "table", + "data": { + "name": "user_discovery_own_promotions", + "was_declared_in_moor": false, + "columns": [ + { + "name": "version_id", + "getter_name": "versionId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "promotion", + "getter_name": "promotion", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 22, + "references": [ + 0 + ], + "type": "table", + "data": { + "name": "user_discovery_shares", + "was_declared_in_moor": false, + "columns": [ + { + "name": "share_id", + "getter_name": "shareId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "share", + "getter_name": "share", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 23, + "references": [], + "type": "table", + "data": { + "name": "shortcuts", + "was_declared_in_moor": false, + "columns": [ + { + "name": "id", + "getter_name": "id", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "emoji", + "getter_name": "emoji", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "UNIQUE", + "dialectAwareDefaultConstraints": { + "sqlite": "UNIQUE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "unique" + ] + }, + { + "name": "usage_counter", + "getter_name": "usageCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 24, + "references": [ + 23, + 1 + ], + "type": "table", + "data": { + "name": "shortcut_members", + "was_declared_in_moor": false, + "columns": [ + { + "name": "shortcut_id", + "getter_name": "shortcutId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES shortcuts (id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES shortcuts (id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "shortcuts", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "group_id", + "getter_name": "groupId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "groups", + "column": "group_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "shortcut_id", + "group_id" + ] + } + } + ], + "fixed_sql": [ + { + "name": "contacts", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"contacts\" (\"user_id\" INTEGER NOT NULL, \"username\" TEXT NOT NULL, \"display_name\" TEXT NULL, \"nick_name\" TEXT NULL, \"avatar_svg_compressed\" BLOB NULL, \"sender_profile_counter\" INTEGER NOT NULL DEFAULT 0, \"accepted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"accepted\" IN (0, 1)), \"deleted_by_user\" INTEGER NOT NULL DEFAULT 0 CHECK (\"deleted_by_user\" IN (0, 1)), \"requested\" INTEGER NOT NULL DEFAULT 0 CHECK (\"requested\" IN (0, 1)), \"blocked\" INTEGER NOT NULL DEFAULT 0 CHECK (\"blocked\" IN (0, 1)), \"verified\" INTEGER NOT NULL DEFAULT 0 CHECK (\"verified\" IN (0, 1)), \"account_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"account_deleted\" IN (0, 1)), \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), \"user_discovery_version\" BLOB NULL, \"user_discovery_excluded\" INTEGER NOT NULL DEFAULT 0 CHECK (\"user_discovery_excluded\" IN (0, 1)), \"user_discovery_manual_approved\" INTEGER NULL DEFAULT 0 CHECK (\"user_discovery_manual_approved\" IN (0, 1)), \"recovery_is_trusted_friend\" INTEGER NOT NULL DEFAULT 0 CHECK (\"recovery_is_trusted_friend\" IN (0, 1)), \"recovery_last_heartbeat\" INTEGER NULL, \"recovery_secret_share\" BLOB NULL, \"recovery_contacts_secret_share\" BLOB NULL, \"recovery_contacts_last_heartbeat\" INTEGER NULL, \"ask_for_friend_promotions\" INTEGER NULL CHECK (\"ask_for_friend_promotions\" IN (0, 1)), \"media_send_counter\" INTEGER NOT NULL DEFAULT 0, \"media_received_counter\" INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (\"user_id\"));" + } + ] + }, + { + "name": "groups", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"groups\" (\"group_id\" TEXT NOT NULL, \"is_group_admin\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_group_admin\" IN (0, 1)), \"is_direct_chat\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_direct_chat\" IN (0, 1)), \"pinned\" INTEGER NOT NULL DEFAULT 0 CHECK (\"pinned\" IN (0, 1)), \"archived\" INTEGER NOT NULL DEFAULT 0 CHECK (\"archived\" IN (0, 1)), \"joined_group\" INTEGER NOT NULL DEFAULT 0 CHECK (\"joined_group\" IN (0, 1)), \"left_group\" INTEGER NOT NULL DEFAULT 0 CHECK (\"left_group\" IN (0, 1)), \"deleted_content\" INTEGER NOT NULL DEFAULT 0 CHECK (\"deleted_content\" IN (0, 1)), \"state_version_id\" INTEGER NOT NULL DEFAULT 0, \"state_encryption_key\" BLOB NULL, \"my_group_private_key\" BLOB NULL, \"group_name\" TEXT NOT NULL, \"draft_message\" TEXT NULL, \"total_media_counter\" INTEGER NOT NULL DEFAULT 0, \"also_best_friend\" INTEGER NOT NULL DEFAULT 0 CHECK (\"also_best_friend\" IN (0, 1)), \"delete_messages_after_milliseconds\" INTEGER NOT NULL DEFAULT 86400000, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), \"last_message_send\" INTEGER NULL, \"last_message_received\" INTEGER NULL, \"last_flame_counter_change\" INTEGER NULL, \"last_flame_sync\" INTEGER NULL, \"flame_counter\" INTEGER NOT NULL DEFAULT 0, \"max_flame_counter\" INTEGER NOT NULL DEFAULT 0, \"max_flame_counter_from\" INTEGER NULL, \"last_message_exchange\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"group_id\"));" + } + ] + }, + { + "name": "media_files", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"media_files\" (\"media_id\" TEXT NOT NULL, \"type\" TEXT NOT NULL, \"upload_state\" TEXT NULL, \"download_state\" TEXT NULL, \"requires_authentication\" INTEGER NOT NULL DEFAULT 0 CHECK (\"requires_authentication\" IN (0, 1)), \"stored\" INTEGER NOT NULL DEFAULT 0 CHECK (\"stored\" IN (0, 1)), \"is_draft_media\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_draft_media\" IN (0, 1)), \"is_favorite\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_favorite\" IN (0, 1)), \"has_crop_analyzed\" INTEGER NOT NULL DEFAULT 0 CHECK (\"has_crop_analyzed\" IN (0, 1)), \"pre_progressing_process\" INTEGER NULL, \"reupload_requested_by\" TEXT NULL, \"display_limit_in_milliseconds\" INTEGER NULL, \"remove_audio\" INTEGER NULL CHECK (\"remove_audio\" IN (0, 1)), \"download_token\" BLOB NULL, \"encryption_key\" BLOB NULL, \"encryption_mac\" BLOB NULL, \"encryption_nonce\" BLOB NULL, \"stored_file_hash\" BLOB NULL, \"has_thumbnail\" INTEGER NOT NULL DEFAULT 0 CHECK (\"has_thumbnail\" IN (0, 1)), \"size_in_bytes\" INTEGER NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), \"created_at_month\" TEXT NULL, PRIMARY KEY (\"media_id\"));" + } + ] + }, + { + "name": "messages", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"messages\" (\"group_id\" TEXT NOT NULL REFERENCES \"groups\" (group_id) ON DELETE CASCADE, \"message_id\" TEXT NOT NULL, \"sender_id\" INTEGER NULL REFERENCES contacts (user_id), \"type\" TEXT NOT NULL, \"content\" TEXT NULL, \"media_id\" TEXT NULL REFERENCES media_files (media_id) ON DELETE SET NULL, \"additional_message_data\" BLOB NULL, \"media_stored\" INTEGER NOT NULL DEFAULT 0 CHECK (\"media_stored\" IN (0, 1)), \"media_reopened\" INTEGER NOT NULL DEFAULT 0 CHECK (\"media_reopened\" IN (0, 1)), \"download_token\" BLOB NULL, \"quotes_message_id\" TEXT NULL, \"is_deleted_from_sender\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted_from_sender\" IN (0, 1)), \"opened_at\" INTEGER NULL, \"opened_by_all\" INTEGER NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), \"modified_at\" INTEGER NULL, \"ack_by_user\" INTEGER NULL, \"ack_by_server\" INTEGER NULL, PRIMARY KEY (\"message_id\"));" + } + ] + }, + { + "name": "message_histories", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"message_histories\" (\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"message_id\" TEXT NOT NULL REFERENCES messages (message_id) ON DELETE CASCADE, \"contact_id\" INTEGER NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"content\" TEXT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)));" + } + ] + }, + { + "name": "reactions", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"reactions\" (\"message_id\" TEXT NOT NULL REFERENCES messages (message_id) ON DELETE CASCADE, \"emoji\" TEXT NOT NULL, \"sender_id\" INTEGER NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"message_id\", \"sender_id\", \"emoji\"));" + } + ] + }, + { + "name": "group_members", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"group_members\" (\"group_id\" TEXT NOT NULL REFERENCES \"groups\" (group_id) ON DELETE CASCADE, \"contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id), \"member_state\" TEXT NULL, \"group_public_key\" BLOB NULL, \"last_chat_opened\" INTEGER NULL, \"last_type_indicator\" INTEGER NULL, \"last_message\" INTEGER NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"group_id\", \"contact_id\"));" + } + ] + }, + { + "name": "receipts", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"receipts\" (\"receipt_id\" TEXT NOT NULL, \"contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"message_id\" TEXT NULL REFERENCES messages (message_id) ON DELETE CASCADE, \"message\" BLOB NOT NULL, \"contact_will_sends_receipt\" INTEGER NOT NULL DEFAULT 1 CHECK (\"contact_will_sends_receipt\" IN (0, 1)), \"will_be_retried_by_media_upload\" INTEGER NOT NULL DEFAULT 0 CHECK (\"will_be_retried_by_media_upload\" IN (0, 1)), \"mark_for_retry\" INTEGER NULL, \"mark_for_retry_after_accepted\" INTEGER NULL, \"ack_by_server_at\" INTEGER NULL, \"retry_count\" INTEGER NOT NULL DEFAULT 0, \"last_retry\" INTEGER NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"receipt_id\"));" + } + ] + }, + { + "name": "received_receipts", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"received_receipts\" (\"receipt_id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"receipt_id\"));" + } + ] + }, + { + "name": "signal_identity_key_stores", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"signal_identity_key_stores\" (\"device_id\" INTEGER NOT NULL, \"name\" TEXT NOT NULL, \"identity_key\" BLOB NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"device_id\", \"name\"));" + } + ] + }, + { + "name": "signal_pre_key_stores", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"signal_pre_key_stores\" (\"pre_key_id\" INTEGER NOT NULL, \"pre_key\" BLOB NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"pre_key_id\"));" + } + ] + }, + { + "name": "signal_sender_key_stores", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"signal_sender_key_stores\" (\"sender_key_name\" TEXT NOT NULL, \"sender_key\" BLOB NOT NULL, PRIMARY KEY (\"sender_key_name\"));" + } + ] + }, + { + "name": "signal_session_stores", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"signal_session_stores\" (\"device_id\" INTEGER NOT NULL, \"name\" TEXT NOT NULL, \"session_record\" BLOB NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"device_id\", \"name\"));" + } + ] + }, + { + "name": "signal_signed_pre_key_stores", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"signal_signed_pre_key_stores\" (\"signed_pre_key_id\" INTEGER NOT NULL, \"signed_pre_key\" BLOB NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"signed_pre_key_id\"));" + } + ] + }, + { + "name": "message_actions", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"message_actions\" (\"message_id\" TEXT NOT NULL REFERENCES messages (message_id) ON DELETE CASCADE, \"contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"type\" TEXT NOT NULL, \"action_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"message_id\", \"contact_id\", \"type\"));" + } + ] + }, + { + "name": "group_histories", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"group_histories\" (\"group_history_id\" TEXT NOT NULL, \"group_id\" TEXT NOT NULL REFERENCES \"groups\" (group_id) ON DELETE CASCADE, \"contact_id\" INTEGER NULL REFERENCES contacts (user_id), \"affected_contact_id\" INTEGER NULL, \"old_group_name\" TEXT NULL, \"new_group_name\" TEXT NULL, \"new_delete_messages_after_milliseconds\" INTEGER NULL, \"type\" TEXT NOT NULL, \"action_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"group_history_id\"));" + } + ] + }, + { + "name": "key_verifications", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"key_verifications\" (\"verification_id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"type\" TEXT NOT NULL, \"verified_by\" INTEGER NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)));" + } + ] + }, + { + "name": "verification_tokens", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"verification_tokens\" (\"token_id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"token\" BLOB NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)));" + } + ] + }, + { + "name": "user_discovery_announced_users", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_discovery_announced_users\" (\"announced_user_id\" INTEGER NOT NULL, \"announced_public_key\" BLOB NOT NULL, \"public_id\" INTEGER NOT NULL UNIQUE, \"username\" TEXT NULL, \"was_shown_to_the_user\" INTEGER NOT NULL DEFAULT 0 CHECK (\"was_shown_to_the_user\" IN (0, 1)), \"is_hidden\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_hidden\" IN (0, 1)), \"was_asked_friends\" INTEGER NOT NULL DEFAULT 0 CHECK (\"was_asked_friends\" IN (0, 1)), PRIMARY KEY (\"announced_user_id\"));" + } + ] + }, + { + "name": "user_discovery_user_relations", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_discovery_user_relations\" (\"announced_user_id\" INTEGER NOT NULL REFERENCES user_discovery_announced_users (announced_user_id) ON DELETE CASCADE, \"from_contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"public_key_verified_timestamp\" INTEGER NULL, PRIMARY KEY (\"announced_user_id\", \"from_contact_id\"));" + } + ] + }, + { + "name": "user_discovery_other_promotions", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_discovery_other_promotions\" (\"from_contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"promotion_id\" INTEGER NOT NULL, \"public_id\" INTEGER NOT NULL, \"threshold\" INTEGER NOT NULL, \"announcement_share\" BLOB NOT NULL, \"public_key_verified_timestamp\" INTEGER NULL, PRIMARY KEY (\"from_contact_id\", \"public_id\"));" + } + ] + }, + { + "name": "user_discovery_own_promotions", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_discovery_own_promotions\" (\"version_id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"promotion\" BLOB NOT NULL);" + } + ] + }, + { + "name": "user_discovery_shares", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_discovery_shares\" (\"share_id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"share\" BLOB NOT NULL, \"contact_id\" INTEGER NULL REFERENCES contacts (user_id) ON DELETE CASCADE);" + } + ] + }, + { + "name": "shortcuts", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"shortcuts\" (\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"emoji\" TEXT NOT NULL UNIQUE, \"usage_counter\" INTEGER NOT NULL DEFAULT 0);" + } + ] + }, + { + "name": "shortcut_members", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"shortcut_members\" (\"shortcut_id\" INTEGER NOT NULL REFERENCES shortcuts (id) ON DELETE CASCADE, \"group_id\" TEXT NOT NULL REFERENCES \"groups\" (group_id) ON DELETE CASCADE, PRIMARY KEY (\"shortcut_id\", \"group_id\"));" + } + ] + } + ] +} \ No newline at end of file diff --git a/lib/src/database/tables/contacts.table.dart b/lib/src/database/tables/contacts.table.dart index e70cecd2..b13b776b 100644 --- a/lib/src/database/tables/contacts.table.dart +++ b/lib/src/database/tables/contacts.table.dart @@ -36,6 +36,10 @@ class Contacts extends Table { DateTimeColumn get recoveryLastHeartbeat => dateTime().nullable()(); BlobColumn get recoverySecretShare => blob().nullable()(); + // This is the share from the contact in case the contact has selected this user as his trusted friend. + BlobColumn get recoveryContactsSecretShare => blob().nullable()(); + DateTimeColumn get recoveryContactsLastHeartbeat => dateTime().nullable()(); + BoolColumn get askForFriendPromotions => boolean().nullable()(); IntColumn get mediaSendCounter => integer().withDefault(const Constant(0))(); diff --git a/lib/src/database/twonly.db.dart b/lib/src/database/twonly.db.dart index 10ed6bf5..a6ac2901 100644 --- a/lib/src/database/twonly.db.dart +++ b/lib/src/database/twonly.db.dart @@ -82,7 +82,7 @@ class TwonlyDB extends _$TwonlyDB { TwonlyDB.forTesting(DatabaseConnection super.connection); @override - int get schemaVersion => 20; + int get schemaVersion => 21; static QueryExecutor _openConnection() { final connection = driftDatabase( @@ -259,6 +259,16 @@ class TwonlyDB extends _$TwonlyDB { schema.contacts.recoverySecretShare, ); }, + from20To21: (m, schema) async { + await m.addColumn( + schema.contacts, + schema.contacts.recoveryContactsSecretShare, + ); + await m.addColumn( + schema.contacts, + schema.contacts.recoveryContactsLastHeartbeat, + ); + }, )(m, from, to); }, ); diff --git a/lib/src/database/twonly.db.g.dart b/lib/src/database/twonly.db.g.dart index 2f206802..7c69f78e 100644 --- a/lib/src/database/twonly.db.g.dart +++ b/lib/src/database/twonly.db.g.dart @@ -252,6 +252,28 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> { type: DriftSqlType.blob, requiredDuringInsert: false, ); + static const VerificationMeta _recoveryContactsSecretShareMeta = + const VerificationMeta('recoveryContactsSecretShare'); + @override + late final GeneratedColumn recoveryContactsSecretShare = + GeneratedColumn( + 'recovery_contacts_secret_share', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + ); + static const VerificationMeta _recoveryContactsLastHeartbeatMeta = + const VerificationMeta('recoveryContactsLastHeartbeat'); + @override + late final GeneratedColumn recoveryContactsLastHeartbeat = + GeneratedColumn( + 'recovery_contacts_last_heartbeat', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); static const VerificationMeta _askForFriendPromotionsMeta = const VerificationMeta('askForFriendPromotions'); @override @@ -310,6 +332,8 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> { recoveryIsTrustedFriend, recoveryLastHeartbeat, recoverySecretShare, + recoveryContactsSecretShare, + recoveryContactsLastHeartbeat, askForFriendPromotions, mediaSendCounter, mediaReceivedCounter, @@ -475,6 +499,24 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> { ), ); } + if (data.containsKey('recovery_contacts_secret_share')) { + context.handle( + _recoveryContactsSecretShareMeta, + recoveryContactsSecretShare.isAcceptableOrUnknown( + data['recovery_contacts_secret_share']!, + _recoveryContactsSecretShareMeta, + ), + ); + } + if (data.containsKey('recovery_contacts_last_heartbeat')) { + context.handle( + _recoveryContactsLastHeartbeatMeta, + recoveryContactsLastHeartbeat.isAcceptableOrUnknown( + data['recovery_contacts_last_heartbeat']!, + _recoveryContactsLastHeartbeatMeta, + ), + ); + } if (data.containsKey('ask_for_friend_promotions')) { context.handle( _askForFriendPromotionsMeta, @@ -587,6 +629,14 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> { DriftSqlType.blob, data['${effectivePrefix}recovery_secret_share'], ), + recoveryContactsSecretShare: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}recovery_contacts_secret_share'], + ), + recoveryContactsLastHeartbeat: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}recovery_contacts_last_heartbeat'], + ), askForFriendPromotions: attachedDatabase.typeMapping.read( DriftSqlType.bool, data['${effectivePrefix}ask_for_friend_promotions'], @@ -628,6 +678,8 @@ class Contact extends DataClass implements Insertable { final bool recoveryIsTrustedFriend; final DateTime? recoveryLastHeartbeat; final Uint8List? recoverySecretShare; + final Uint8List? recoveryContactsSecretShare; + final DateTime? recoveryContactsLastHeartbeat; final bool? askForFriendPromotions; final int mediaSendCounter; final int mediaReceivedCounter; @@ -651,6 +703,8 @@ class Contact extends DataClass implements Insertable { required this.recoveryIsTrustedFriend, this.recoveryLastHeartbeat, this.recoverySecretShare, + this.recoveryContactsSecretShare, + this.recoveryContactsLastHeartbeat, this.askForFriendPromotions, required this.mediaSendCounter, required this.mediaReceivedCounter, @@ -695,6 +749,16 @@ class Contact extends DataClass implements Insertable { if (!nullToAbsent || recoverySecretShare != null) { map['recovery_secret_share'] = Variable(recoverySecretShare); } + if (!nullToAbsent || recoveryContactsSecretShare != null) { + map['recovery_contacts_secret_share'] = Variable( + recoveryContactsSecretShare, + ); + } + if (!nullToAbsent || recoveryContactsLastHeartbeat != null) { + map['recovery_contacts_last_heartbeat'] = Variable( + recoveryContactsLastHeartbeat, + ); + } if (!nullToAbsent || askForFriendPromotions != null) { map['ask_for_friend_promotions'] = Variable(askForFriendPromotions); } @@ -739,6 +803,14 @@ class Contact extends DataClass implements Insertable { recoverySecretShare: recoverySecretShare == null && nullToAbsent ? const Value.absent() : Value(recoverySecretShare), + recoveryContactsSecretShare: + recoveryContactsSecretShare == null && nullToAbsent + ? const Value.absent() + : Value(recoveryContactsSecretShare), + recoveryContactsLastHeartbeat: + recoveryContactsLastHeartbeat == null && nullToAbsent + ? const Value.absent() + : Value(recoveryContactsLastHeartbeat), askForFriendPromotions: askForFriendPromotions == null && nullToAbsent ? const Value.absent() : Value(askForFriendPromotions), @@ -788,6 +860,12 @@ class Contact extends DataClass implements Insertable { recoverySecretShare: serializer.fromJson( json['recoverySecretShare'], ), + recoveryContactsSecretShare: serializer.fromJson( + json['recoveryContactsSecretShare'], + ), + recoveryContactsLastHeartbeat: serializer.fromJson( + json['recoveryContactsLastHeartbeat'], + ), askForFriendPromotions: serializer.fromJson( json['askForFriendPromotions'], ), @@ -828,6 +906,12 @@ class Contact extends DataClass implements Insertable { recoveryLastHeartbeat, ), 'recoverySecretShare': serializer.toJson(recoverySecretShare), + 'recoveryContactsSecretShare': serializer.toJson( + recoveryContactsSecretShare, + ), + 'recoveryContactsLastHeartbeat': serializer.toJson( + recoveryContactsLastHeartbeat, + ), 'askForFriendPromotions': serializer.toJson( askForFriendPromotions, ), @@ -856,6 +940,8 @@ class Contact extends DataClass implements Insertable { bool? recoveryIsTrustedFriend, Value recoveryLastHeartbeat = const Value.absent(), Value recoverySecretShare = const Value.absent(), + Value recoveryContactsSecretShare = const Value.absent(), + Value recoveryContactsLastHeartbeat = const Value.absent(), Value askForFriendPromotions = const Value.absent(), int? mediaSendCounter, int? mediaReceivedCounter, @@ -890,6 +976,12 @@ class Contact extends DataClass implements Insertable { recoverySecretShare: recoverySecretShare.present ? recoverySecretShare.value : this.recoverySecretShare, + recoveryContactsSecretShare: recoveryContactsSecretShare.present + ? recoveryContactsSecretShare.value + : this.recoveryContactsSecretShare, + recoveryContactsLastHeartbeat: recoveryContactsLastHeartbeat.present + ? recoveryContactsLastHeartbeat.value + : this.recoveryContactsLastHeartbeat, askForFriendPromotions: askForFriendPromotions.present ? askForFriendPromotions.value : this.askForFriendPromotions, @@ -939,6 +1031,12 @@ class Contact extends DataClass implements Insertable { recoverySecretShare: data.recoverySecretShare.present ? data.recoverySecretShare.value : this.recoverySecretShare, + recoveryContactsSecretShare: data.recoveryContactsSecretShare.present + ? data.recoveryContactsSecretShare.value + : this.recoveryContactsSecretShare, + recoveryContactsLastHeartbeat: data.recoveryContactsLastHeartbeat.present + ? data.recoveryContactsLastHeartbeat.value + : this.recoveryContactsLastHeartbeat, askForFriendPromotions: data.askForFriendPromotions.present ? data.askForFriendPromotions.value : this.askForFriendPromotions, @@ -973,6 +1071,10 @@ class Contact extends DataClass implements Insertable { ..write('recoveryIsTrustedFriend: $recoveryIsTrustedFriend, ') ..write('recoveryLastHeartbeat: $recoveryLastHeartbeat, ') ..write('recoverySecretShare: $recoverySecretShare, ') + ..write('recoveryContactsSecretShare: $recoveryContactsSecretShare, ') + ..write( + 'recoveryContactsLastHeartbeat: $recoveryContactsLastHeartbeat, ', + ) ..write('askForFriendPromotions: $askForFriendPromotions, ') ..write('mediaSendCounter: $mediaSendCounter, ') ..write('mediaReceivedCounter: $mediaReceivedCounter') @@ -1001,6 +1103,8 @@ class Contact extends DataClass implements Insertable { recoveryIsTrustedFriend, recoveryLastHeartbeat, $driftBlobEquality.hash(recoverySecretShare), + $driftBlobEquality.hash(recoveryContactsSecretShare), + recoveryContactsLastHeartbeat, askForFriendPromotions, mediaSendCounter, mediaReceivedCounter, @@ -1038,6 +1142,12 @@ class Contact extends DataClass implements Insertable { other.recoverySecretShare, this.recoverySecretShare, ) && + $driftBlobEquality.equals( + other.recoveryContactsSecretShare, + this.recoveryContactsSecretShare, + ) && + other.recoveryContactsLastHeartbeat == + this.recoveryContactsLastHeartbeat && other.askForFriendPromotions == this.askForFriendPromotions && other.mediaSendCounter == this.mediaSendCounter && other.mediaReceivedCounter == this.mediaReceivedCounter); @@ -1063,6 +1173,8 @@ class ContactsCompanion extends UpdateCompanion { final Value recoveryIsTrustedFriend; final Value recoveryLastHeartbeat; final Value recoverySecretShare; + final Value recoveryContactsSecretShare; + final Value recoveryContactsLastHeartbeat; final Value askForFriendPromotions; final Value mediaSendCounter; final Value mediaReceivedCounter; @@ -1086,6 +1198,8 @@ class ContactsCompanion extends UpdateCompanion { this.recoveryIsTrustedFriend = const Value.absent(), this.recoveryLastHeartbeat = const Value.absent(), this.recoverySecretShare = const Value.absent(), + this.recoveryContactsSecretShare = const Value.absent(), + this.recoveryContactsLastHeartbeat = const Value.absent(), this.askForFriendPromotions = const Value.absent(), this.mediaSendCounter = const Value.absent(), this.mediaReceivedCounter = const Value.absent(), @@ -1110,6 +1224,8 @@ class ContactsCompanion extends UpdateCompanion { this.recoveryIsTrustedFriend = const Value.absent(), this.recoveryLastHeartbeat = const Value.absent(), this.recoverySecretShare = const Value.absent(), + this.recoveryContactsSecretShare = const Value.absent(), + this.recoveryContactsLastHeartbeat = const Value.absent(), this.askForFriendPromotions = const Value.absent(), this.mediaSendCounter = const Value.absent(), this.mediaReceivedCounter = const Value.absent(), @@ -1134,6 +1250,8 @@ class ContactsCompanion extends UpdateCompanion { Expression? recoveryIsTrustedFriend, Expression? recoveryLastHeartbeat, Expression? recoverySecretShare, + Expression? recoveryContactsSecretShare, + Expression? recoveryContactsLastHeartbeat, Expression? askForFriendPromotions, Expression? mediaSendCounter, Expression? mediaReceivedCounter, @@ -1166,6 +1284,10 @@ class ContactsCompanion extends UpdateCompanion { 'recovery_last_heartbeat': recoveryLastHeartbeat, if (recoverySecretShare != null) 'recovery_secret_share': recoverySecretShare, + if (recoveryContactsSecretShare != null) + 'recovery_contacts_secret_share': recoveryContactsSecretShare, + if (recoveryContactsLastHeartbeat != null) + 'recovery_contacts_last_heartbeat': recoveryContactsLastHeartbeat, if (askForFriendPromotions != null) 'ask_for_friend_promotions': askForFriendPromotions, if (mediaSendCounter != null) 'media_send_counter': mediaSendCounter, @@ -1194,6 +1316,8 @@ class ContactsCompanion extends UpdateCompanion { Value? recoveryIsTrustedFriend, Value? recoveryLastHeartbeat, Value? recoverySecretShare, + Value? recoveryContactsSecretShare, + Value? recoveryContactsLastHeartbeat, Value? askForFriendPromotions, Value? mediaSendCounter, Value? mediaReceivedCounter, @@ -1222,6 +1346,10 @@ class ContactsCompanion extends UpdateCompanion { recoveryLastHeartbeat: recoveryLastHeartbeat ?? this.recoveryLastHeartbeat, recoverySecretShare: recoverySecretShare ?? this.recoverySecretShare, + recoveryContactsSecretShare: + recoveryContactsSecretShare ?? this.recoveryContactsSecretShare, + recoveryContactsLastHeartbeat: + recoveryContactsLastHeartbeat ?? this.recoveryContactsLastHeartbeat, askForFriendPromotions: askForFriendPromotions ?? this.askForFriendPromotions, mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter, @@ -1303,6 +1431,16 @@ class ContactsCompanion extends UpdateCompanion { recoverySecretShare.value, ); } + if (recoveryContactsSecretShare.present) { + map['recovery_contacts_secret_share'] = Variable( + recoveryContactsSecretShare.value, + ); + } + if (recoveryContactsLastHeartbeat.present) { + map['recovery_contacts_last_heartbeat'] = Variable( + recoveryContactsLastHeartbeat.value, + ); + } if (askForFriendPromotions.present) { map['ask_for_friend_promotions'] = Variable( askForFriendPromotions.value, @@ -1339,6 +1477,10 @@ class ContactsCompanion extends UpdateCompanion { ..write('recoveryIsTrustedFriend: $recoveryIsTrustedFriend, ') ..write('recoveryLastHeartbeat: $recoveryLastHeartbeat, ') ..write('recoverySecretShare: $recoverySecretShare, ') + ..write('recoveryContactsSecretShare: $recoveryContactsSecretShare, ') + ..write( + 'recoveryContactsLastHeartbeat: $recoveryContactsLastHeartbeat, ', + ) ..write('askForFriendPromotions: $askForFriendPromotions, ') ..write('mediaSendCounter: $mediaSendCounter, ') ..write('mediaReceivedCounter: $mediaReceivedCounter') @@ -13121,6 +13263,8 @@ typedef $$ContactsTableCreateCompanionBuilder = Value recoveryIsTrustedFriend, Value recoveryLastHeartbeat, Value recoverySecretShare, + Value recoveryContactsSecretShare, + Value recoveryContactsLastHeartbeat, Value askForFriendPromotions, Value mediaSendCounter, Value mediaReceivedCounter, @@ -13146,6 +13290,8 @@ typedef $$ContactsTableUpdateCompanionBuilder = Value recoveryIsTrustedFriend, Value recoveryLastHeartbeat, Value recoverySecretShare, + Value recoveryContactsSecretShare, + Value recoveryContactsLastHeartbeat, Value askForFriendPromotions, Value mediaSendCounter, Value mediaReceivedCounter, @@ -13525,6 +13671,18 @@ class $$ContactsTableFilterComposer builder: (column) => ColumnFilters(column), ); + ColumnFilters get recoveryContactsSecretShare => + $composableBuilder( + column: $table.recoveryContactsSecretShare, + builder: (column) => ColumnFilters(column), + ); + + ColumnFilters get recoveryContactsLastHeartbeat => + $composableBuilder( + column: $table.recoveryContactsLastHeartbeat, + builder: (column) => ColumnFilters(column), + ); + ColumnFilters get askForFriendPromotions => $composableBuilder( column: $table.askForFriendPromotions, builder: (column) => ColumnFilters(column), @@ -13928,6 +14086,18 @@ class $$ContactsTableOrderingComposer builder: (column) => ColumnOrderings(column), ); + ColumnOrderings get recoveryContactsSecretShare => + $composableBuilder( + column: $table.recoveryContactsSecretShare, + builder: (column) => ColumnOrderings(column), + ); + + ColumnOrderings get recoveryContactsLastHeartbeat => + $composableBuilder( + column: $table.recoveryContactsLastHeartbeat, + builder: (column) => ColumnOrderings(column), + ); + ColumnOrderings get askForFriendPromotions => $composableBuilder( column: $table.askForFriendPromotions, builder: (column) => ColumnOrderings(column), @@ -14032,6 +14202,18 @@ class $$ContactsTableAnnotationComposer builder: (column) => column, ); + GeneratedColumn get recoveryContactsSecretShare => + $composableBuilder( + column: $table.recoveryContactsSecretShare, + builder: (column) => column, + ); + + GeneratedColumn get recoveryContactsLastHeartbeat => + $composableBuilder( + column: $table.recoveryContactsLastHeartbeat, + builder: (column) => column, + ); + GeneratedColumn get askForFriendPromotions => $composableBuilder( column: $table.askForFriendPromotions, builder: (column) => column, @@ -14395,6 +14577,10 @@ class $$ContactsTableTableManager Value recoveryIsTrustedFriend = const Value.absent(), Value recoveryLastHeartbeat = const Value.absent(), Value recoverySecretShare = const Value.absent(), + Value recoveryContactsSecretShare = + const Value.absent(), + Value recoveryContactsLastHeartbeat = + const Value.absent(), Value askForFriendPromotions = const Value.absent(), Value mediaSendCounter = const Value.absent(), Value mediaReceivedCounter = const Value.absent(), @@ -14418,6 +14604,8 @@ class $$ContactsTableTableManager recoveryIsTrustedFriend: recoveryIsTrustedFriend, recoveryLastHeartbeat: recoveryLastHeartbeat, recoverySecretShare: recoverySecretShare, + recoveryContactsSecretShare: recoveryContactsSecretShare, + recoveryContactsLastHeartbeat: recoveryContactsLastHeartbeat, askForFriendPromotions: askForFriendPromotions, mediaSendCounter: mediaSendCounter, mediaReceivedCounter: mediaReceivedCounter, @@ -14443,6 +14631,10 @@ class $$ContactsTableTableManager Value recoveryIsTrustedFriend = const Value.absent(), Value recoveryLastHeartbeat = const Value.absent(), Value recoverySecretShare = const Value.absent(), + Value recoveryContactsSecretShare = + const Value.absent(), + Value recoveryContactsLastHeartbeat = + const Value.absent(), Value askForFriendPromotions = const Value.absent(), Value mediaSendCounter = const Value.absent(), Value mediaReceivedCounter = const Value.absent(), @@ -14466,6 +14658,8 @@ class $$ContactsTableTableManager recoveryIsTrustedFriend: recoveryIsTrustedFriend, recoveryLastHeartbeat: recoveryLastHeartbeat, recoverySecretShare: recoverySecretShare, + recoveryContactsSecretShare: recoveryContactsSecretShare, + recoveryContactsLastHeartbeat: recoveryContactsLastHeartbeat, askForFriendPromotions: askForFriendPromotions, mediaSendCounter: mediaSendCounter, mediaReceivedCounter: mediaReceivedCounter, diff --git a/lib/src/database/twonly.db.steps.dart b/lib/src/database/twonly.db.steps.dart index 79b53547..14901bd7 100644 --- a/lib/src/database/twonly.db.steps.dart +++ b/lib/src/database/twonly.db.steps.dart @@ -10537,6 +10537,540 @@ i1.GeneratedColumn _column_251(String aliasedName) => type: i1.DriftSqlType.blob, $customConstraints: 'NULL', ); + +final class Schema21 extends i0.VersionedSchema { + Schema21({required super.database}) : super(version: 21); + @override + late final List entities = [ + contacts, + groups, + mediaFiles, + messages, + messageHistories, + reactions, + groupMembers, + receipts, + receivedReceipts, + signalIdentityKeyStores, + signalPreKeyStores, + signalSenderKeyStores, + signalSessionStores, + signalSignedPreKeyStores, + messageActions, + groupHistories, + keyVerifications, + verificationTokens, + userDiscoveryAnnouncedUsers, + userDiscoveryUserRelations, + userDiscoveryOtherPromotions, + userDiscoveryOwnPromotions, + userDiscoveryShares, + shortcuts, + shortcutMembers, + ]; + late final Shape56 contacts = Shape56( + source: i0.VersionedTable( + entityName: 'contacts', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(user_id)'], + columns: [ + _column_106, + _column_107, + _column_108, + _column_109, + _column_110, + _column_111, + _column_112, + _column_113, + _column_114, + _column_115, + _column_116, + _column_117, + _column_118, + _column_211, + _column_212, + _column_213, + _column_249, + _column_250, + _column_251, + _column_252, + _column_253, + _column_247, + _column_214, + _column_215, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape23 groups = Shape23( + source: i0.VersionedTable( + entityName: 'groups', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(group_id)'], + columns: [ + _column_119, + _column_120, + _column_121, + _column_122, + _column_123, + _column_124, + _column_125, + _column_126, + _column_127, + _column_128, + _column_129, + _column_130, + _column_131, + _column_132, + _column_133, + _column_134, + _column_118, + _column_135, + _column_136, + _column_137, + _column_138, + _column_139, + _column_140, + _column_141, + _column_142, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape51 mediaFiles = Shape51( + source: i0.VersionedTable( + entityName: 'media_files', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(media_id)'], + columns: [ + _column_143, + _column_144, + _column_145, + _column_146, + _column_147, + _column_148, + _column_149, + _column_239, + _column_240, + _column_207, + _column_150, + _column_151, + _column_152, + _column_153, + _column_154, + _column_155, + _column_156, + _column_157, + _column_244, + _column_245, + _column_118, + _column_241, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape25 messages = Shape25( + source: i0.VersionedTable( + entityName: 'messages', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(message_id)'], + columns: [ + _column_158, + _column_159, + _column_160, + _column_144, + _column_161, + _column_162, + _column_163, + _column_164, + _column_165, + _column_153, + _column_166, + _column_167, + _column_168, + _column_169, + _column_118, + _column_170, + _column_171, + _column_172, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape26 messageHistories = Shape26( + source: i0.VersionedTable( + entityName: 'message_histories', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [ + _column_173, + _column_174, + _column_175, + _column_161, + _column_118, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape27 reactions = Shape27( + source: i0.VersionedTable( + entityName: 'reactions', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(message_id, sender_id, emoji)'], + columns: [_column_174, _column_176, _column_177, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape38 groupMembers = Shape38( + source: i0.VersionedTable( + entityName: 'group_members', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(group_id, contact_id)'], + columns: [ + _column_158, + _column_178, + _column_179, + _column_180, + _column_209, + _column_210, + _column_181, + _column_118, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape37 receipts = Shape37( + source: i0.VersionedTable( + entityName: 'receipts', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(receipt_id)'], + columns: [ + _column_182, + _column_183, + _column_184, + _column_185, + _column_186, + _column_208, + _column_187, + _column_188, + _column_189, + _column_190, + _column_191, + _column_118, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape30 receivedReceipts = Shape30( + source: i0.VersionedTable( + entityName: 'received_receipts', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(receipt_id)'], + columns: [_column_182, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape31 signalIdentityKeyStores = Shape31( + source: i0.VersionedTable( + entityName: 'signal_identity_key_stores', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(device_id, name)'], + columns: [_column_192, _column_193, _column_194, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape32 signalPreKeyStores = Shape32( + source: i0.VersionedTable( + entityName: 'signal_pre_key_stores', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(pre_key_id)'], + columns: [_column_195, _column_196, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape11 signalSenderKeyStores = Shape11( + source: i0.VersionedTable( + entityName: 'signal_sender_key_stores', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(sender_key_name)'], + columns: [_column_197, _column_198], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape33 signalSessionStores = Shape33( + source: i0.VersionedTable( + entityName: 'signal_session_stores', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(device_id, name)'], + columns: [_column_192, _column_193, _column_199, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape50 signalSignedPreKeyStores = Shape50( + source: i0.VersionedTable( + entityName: 'signal_signed_pre_key_stores', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(signed_pre_key_id)'], + columns: [_column_242, _column_243, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape34 messageActions = Shape34( + source: i0.VersionedTable( + entityName: 'message_actions', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(message_id, contact_id, type)'], + columns: [_column_174, _column_183, _column_144, _column_200], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape35 groupHistories = Shape35( + source: i0.VersionedTable( + entityName: 'group_histories', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(group_history_id)'], + columns: [ + _column_201, + _column_158, + _column_202, + _column_203, + _column_204, + _column_205, + _column_206, + _column_144, + _column_200, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape54 keyVerifications = Shape54( + source: i0.VersionedTable( + entityName: 'key_verifications', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [ + _column_216, + _column_183, + _column_144, + _column_248, + _column_118, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape41 verificationTokens = Shape41( + source: i0.VersionedTable( + entityName: 'verification_tokens', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [_column_217, _column_218, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape52 userDiscoveryAnnouncedUsers = Shape52( + source: i0.VersionedTable( + entityName: 'user_discovery_announced_users', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(announced_user_id)'], + columns: [ + _column_219, + _column_220, + _column_221, + _column_222, + _column_223, + _column_224, + _column_246, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape43 userDiscoveryUserRelations = Shape43( + source: i0.VersionedTable( + entityName: 'user_discovery_user_relations', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(announced_user_id, from_contact_id)'], + columns: [_column_225, _column_226, _column_227], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape44 userDiscoveryOtherPromotions = Shape44( + source: i0.VersionedTable( + entityName: 'user_discovery_other_promotions', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(from_contact_id, public_id)'], + columns: [ + _column_226, + _column_228, + _column_229, + _column_230, + _column_231, + _column_227, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape45 userDiscoveryOwnPromotions = Shape45( + source: i0.VersionedTable( + entityName: 'user_discovery_own_promotions', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [_column_232, _column_183, _column_233], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape46 userDiscoveryShares = Shape46( + source: i0.VersionedTable( + entityName: 'user_discovery_shares', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [_column_234, _column_235, _column_175], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape47 shortcuts = Shape47( + source: i0.VersionedTable( + entityName: 'shortcuts', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [_column_173, _column_236, _column_237], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape48 shortcutMembers = Shape48( + source: i0.VersionedTable( + entityName: 'shortcut_members', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(shortcut_id, group_id)'], + columns: [_column_238, _column_158], + attachedDatabase: database, + ), + alias: null, + ); +} + +class Shape56 extends i0.VersionedTable { + Shape56({required super.source, required super.alias}) : super.aliased(); + i1.GeneratedColumn get userId => + columnsByName['user_id']! as i1.GeneratedColumn; + i1.GeneratedColumn get username => + columnsByName['username']! as i1.GeneratedColumn; + i1.GeneratedColumn get displayName => + columnsByName['display_name']! as i1.GeneratedColumn; + i1.GeneratedColumn get nickName => + columnsByName['nick_name']! as i1.GeneratedColumn; + i1.GeneratedColumn get avatarSvgCompressed => + columnsByName['avatar_svg_compressed']! + as i1.GeneratedColumn; + i1.GeneratedColumn get senderProfileCounter => + columnsByName['sender_profile_counter']! as i1.GeneratedColumn; + i1.GeneratedColumn get accepted => + columnsByName['accepted']! as i1.GeneratedColumn; + i1.GeneratedColumn get deletedByUser => + columnsByName['deleted_by_user']! as i1.GeneratedColumn; + i1.GeneratedColumn get requested => + columnsByName['requested']! as i1.GeneratedColumn; + i1.GeneratedColumn get blocked => + columnsByName['blocked']! as i1.GeneratedColumn; + i1.GeneratedColumn get verified => + columnsByName['verified']! as i1.GeneratedColumn; + i1.GeneratedColumn get accountDeleted => + columnsByName['account_deleted']! as i1.GeneratedColumn; + i1.GeneratedColumn get createdAt => + columnsByName['created_at']! as i1.GeneratedColumn; + i1.GeneratedColumn get userDiscoveryVersion => + columnsByName['user_discovery_version']! + as i1.GeneratedColumn; + i1.GeneratedColumn get userDiscoveryExcluded => + columnsByName['user_discovery_excluded']! as i1.GeneratedColumn; + i1.GeneratedColumn get userDiscoveryManualApproved => + columnsByName['user_discovery_manual_approved']! + as i1.GeneratedColumn; + i1.GeneratedColumn get recoveryIsTrustedFriend => + columnsByName['recovery_is_trusted_friend']! as i1.GeneratedColumn; + i1.GeneratedColumn get recoveryLastHeartbeat => + columnsByName['recovery_last_heartbeat']! as i1.GeneratedColumn; + i1.GeneratedColumn get recoverySecretShare => + columnsByName['recovery_secret_share']! + as i1.GeneratedColumn; + i1.GeneratedColumn get recoveryContactsSecretShare => + columnsByName['recovery_contacts_secret_share']! + as i1.GeneratedColumn; + i1.GeneratedColumn get recoveryContactsLastHeartbeat => + columnsByName['recovery_contacts_last_heartbeat']! + as i1.GeneratedColumn; + i1.GeneratedColumn get askForFriendPromotions => + columnsByName['ask_for_friend_promotions']! as i1.GeneratedColumn; + i1.GeneratedColumn get mediaSendCounter => + columnsByName['media_send_counter']! as i1.GeneratedColumn; + i1.GeneratedColumn get mediaReceivedCounter => + columnsByName['media_received_counter']! as i1.GeneratedColumn; +} + +i1.GeneratedColumn _column_252(String aliasedName) => + i1.GeneratedColumn( + 'recovery_contacts_secret_share', + aliasedName, + true, + type: i1.DriftSqlType.blob, + $customConstraints: 'NULL', + ); +i1.GeneratedColumn _column_253(String aliasedName) => + i1.GeneratedColumn( + 'recovery_contacts_last_heartbeat', + aliasedName, + true, + type: i1.DriftSqlType.int, + $customConstraints: 'NULL', + ); i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, Schema2 schema) from1To2, required Future Function(i1.Migrator m, Schema3 schema) from2To3, @@ -10557,6 +11091,7 @@ i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, Schema18 schema) from17To18, required Future Function(i1.Migrator m, Schema19 schema) from18To19, required Future Function(i1.Migrator m, Schema20 schema) from19To20, + required Future Function(i1.Migrator m, Schema21 schema) from20To21, }) { return (currentVersion, database) async { switch (currentVersion) { @@ -10655,6 +11190,11 @@ i0.MigrationStepWithVersion migrationSteps({ final migrator = i1.Migrator(database, schema); await from19To20(migrator, schema); return 20; + case 20: + final schema = Schema21(database: database); + final migrator = i1.Migrator(database, schema); + await from20To21(migrator, schema); + return 21; default: throw ArgumentError.value('Unknown migration from $currentVersion'); } @@ -10681,6 +11221,7 @@ i1.OnUpgrade stepByStep({ required Future Function(i1.Migrator m, Schema18 schema) from17To18, required Future Function(i1.Migrator m, Schema19 schema) from18To19, required Future Function(i1.Migrator m, Schema20 schema) from19To20, + required Future Function(i1.Migrator m, Schema21 schema) from20To21, }) => i0.VersionedSchema.stepByStepHelper( step: migrationSteps( from1To2: from1To2, @@ -10702,5 +11243,6 @@ i1.OnUpgrade stepByStep({ from17To18: from17To18, from18To19: from18To19, from19To20: from19To20, + from20To21: from20To21, ), ); diff --git a/lib/src/model/json/userdata.model.dart b/lib/src/model/json/userdata.model.dart index e1d27a81..12e8458a 100644 --- a/lib/src/model/json/userdata.model.dart +++ b/lib/src/model/json/userdata.model.dart @@ -208,22 +208,29 @@ class TwonlySafeBackup { @JsonSerializable() class PasswordLessRecovery { - PasswordLessRecovery({ - this.email, - this.pinSeed, - this.pinUnlockToken, - this.threshold, - this.lastHeartbeat, - }); + PasswordLessRecovery(); factory PasswordLessRecovery.fromJson(Map json) => _$PasswordLessRecoveryFromJson(json); + // Only stored, so the user can see his deposit email address... String? email; - String? pinSeed; - String? pinUnlockToken; - int? threshold; - DateTime? lastHeartbeat; + + // <-- + // Data shared with trusted friends + // Trusted friends are able to brute-force the pin -> Server delets after X tries + List? pinSeed; + List? pinUnlockToken; + + // Stored not on the server, so the server is unable to link a email to a user until the actuall recovery or can + // brute-force the pin + List? encryptedServerKeyNonce; + List? encryptedServerKeyMac; + // ---> + + // Checking with the server that the server data is valid and not delted throug the pin protection for example. + DateTime? lastServerHeartbeat; + List? encryptedServerKey; Map toJson() => _$PasswordLessRecoveryToJson(this); } diff --git a/lib/src/model/json/userdata.model.g.dart b/lib/src/model/json/userdata.model.g.dart index 7dc20fc9..ecef38be 100644 --- a/lib/src/model/json/userdata.model.g.dart +++ b/lib/src/model/json/userdata.model.g.dart @@ -243,15 +243,27 @@ const _$LastBackupUploadStateEnumMap = { PasswordLessRecovery _$PasswordLessRecoveryFromJson( Map json, -) => PasswordLessRecovery( - email: json['email'] as String?, - pinSeed: json['pinSeed'] as String?, - pinUnlockToken: json['pinUnlockToken'] as String?, - threshold: (json['threshold'] as num?)?.toInt(), - lastHeartbeat: json['lastHeartbeat'] == null +) => PasswordLessRecovery() + ..email = json['email'] as String? + ..pinSeed = (json['pinSeed'] as List?) + ?.map((e) => (e as num).toInt()) + .toList() + ..pinUnlockToken = (json['pinUnlockToken'] as List?) + ?.map((e) => (e as num).toInt()) + .toList() + ..encryptedServerKeyNonce = + (json['encryptedServerKeyNonce'] as List?) + ?.map((e) => (e as num).toInt()) + .toList() + ..encryptedServerKeyMac = (json['encryptedServerKeyMac'] as List?) + ?.map((e) => (e as num).toInt()) + .toList() + ..lastServerHeartbeat = json['lastServerHeartbeat'] == null ? null - : DateTime.parse(json['lastHeartbeat'] as String), -); + : DateTime.parse(json['lastServerHeartbeat'] as String) + ..encryptedServerKey = (json['encryptedServerKey'] as List?) + ?.map((e) => (e as num).toInt()) + .toList(); Map _$PasswordLessRecoveryToJson( PasswordLessRecovery instance, @@ -259,6 +271,8 @@ Map _$PasswordLessRecoveryToJson( 'email': instance.email, 'pinSeed': instance.pinSeed, 'pinUnlockToken': instance.pinUnlockToken, - 'threshold': instance.threshold, - 'lastHeartbeat': instance.lastHeartbeat?.toIso8601String(), + 'encryptedServerKeyNonce': instance.encryptedServerKeyNonce, + 'encryptedServerKeyMac': instance.encryptedServerKeyMac, + 'lastServerHeartbeat': instance.lastServerHeartbeat?.toIso8601String(), + 'encryptedServerKey': instance.encryptedServerKey, }; diff --git a/lib/src/model/protobuf/api/websocket/client_to_server.pb.dart b/lib/src/model/protobuf/api/websocket/client_to_server.pb.dart index dc424110..fc0f46fa 100644 --- a/lib/src/model/protobuf/api/websocket/client_to_server.pb.dart +++ b/lib/src/model/protobuf/api/websocket/client_to_server.pb.dart @@ -2182,6 +2182,87 @@ class ApplicationData_Deprecated extends $pb.GeneratedMessage { static ApplicationData_Deprecated? _defaultInstance; } +class ApplicationData_RegisterPasswordLessRecovery + extends $pb.GeneratedMessage { + factory ApplicationData_RegisterPasswordLessRecovery({ + $core.List<$core.int>? pinUnlockToken, + $core.List<$core.int>? encryptedServerKey, + }) { + final result = create(); + if (pinUnlockToken != null) result.pinUnlockToken = pinUnlockToken; + if (encryptedServerKey != null) + result.encryptedServerKey = encryptedServerKey; + return result; + } + + ApplicationData_RegisterPasswordLessRecovery._(); + + factory ApplicationData_RegisterPasswordLessRecovery.fromBuffer( + $core.List<$core.int> data, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(data, registry); + factory ApplicationData_RegisterPasswordLessRecovery.fromJson( + $core.String json, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(json, registry); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'ApplicationData.RegisterPasswordLessRecovery', + package: + const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), + createEmptyInstance: create) + ..a<$core.List<$core.int>>( + 1, _omitFieldNames ? '' : 'pinUnlockToken', $pb.PbFieldType.OY, + protoName: 'pinUnlockToken') + ..a<$core.List<$core.int>>( + 2, _omitFieldNames ? '' : 'encryptedServerKey', $pb.PbFieldType.OY, + protoName: 'encryptedServerKey') + ..hasRequiredFields = false; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + ApplicationData_RegisterPasswordLessRecovery clone() => deepCopy(); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + ApplicationData_RegisterPasswordLessRecovery copyWith( + void Function(ApplicationData_RegisterPasswordLessRecovery) + updates) => + super.copyWith((message) => + updates(message as ApplicationData_RegisterPasswordLessRecovery)) + as ApplicationData_RegisterPasswordLessRecovery; + + @$core.override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static ApplicationData_RegisterPasswordLessRecovery create() => + ApplicationData_RegisterPasswordLessRecovery._(); + @$core.override + ApplicationData_RegisterPasswordLessRecovery createEmptyInstance() => + create(); + @$core.pragma('dart2js:noInline') + static ApplicationData_RegisterPasswordLessRecovery getDefault() => + _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor< + ApplicationData_RegisterPasswordLessRecovery>(create); + static ApplicationData_RegisterPasswordLessRecovery? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get pinUnlockToken => $_getN(0); + @$pb.TagNumber(1) + set pinUnlockToken($core.List<$core.int> value) => $_setBytes(0, value); + @$pb.TagNumber(1) + $core.bool hasPinUnlockToken() => $_has(0); + @$pb.TagNumber(1) + void clearPinUnlockToken() => $_clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get encryptedServerKey => $_getN(1); + @$pb.TagNumber(2) + set encryptedServerKey($core.List<$core.int> value) => $_setBytes(1, value); + @$pb.TagNumber(2) + $core.bool hasEncryptedServerKey() => $_has(1); + @$pb.TagNumber(2) + void clearEncryptedServerKey() => $_clearField(2); +} + enum ApplicationData_ApplicationData { textMessage, getUserByUsername, @@ -2209,6 +2290,7 @@ enum ApplicationData_ApplicationData { ipaForceCheck, addAdditionalUser, setLoginToken, + registerPasswordlessRecovery, notSet } @@ -2240,6 +2322,7 @@ class ApplicationData extends $pb.GeneratedMessage { ApplicationData_IPAForceCheck? ipaForceCheck, ApplicationData_AddAdditionalUser? addAdditionalUser, ApplicationData_SetLoginToken? setLoginToken, + ApplicationData_RegisterPasswordLessRecovery? registerPasswordlessRecovery, }) { final result = create(); if (textMessage != null) result.textMessage = textMessage; @@ -2274,6 +2357,8 @@ class ApplicationData extends $pb.GeneratedMessage { if (ipaForceCheck != null) result.ipaForceCheck = ipaForceCheck; if (addAdditionalUser != null) result.addAdditionalUser = addAdditionalUser; if (setLoginToken != null) result.setLoginToken = setLoginToken; + if (registerPasswordlessRecovery != null) + result.registerPasswordlessRecovery = registerPasswordlessRecovery; return result; } @@ -2314,6 +2399,7 @@ class ApplicationData extends $pb.GeneratedMessage { 28: ApplicationData_ApplicationData.ipaForceCheck, 29: ApplicationData_ApplicationData.addAdditionalUser, 30: ApplicationData_ApplicationData.setLoginToken, + 31: ApplicationData_ApplicationData.registerPasswordlessRecovery, 0: ApplicationData_ApplicationData.notSet }; static final $pb.BuilderInfo _i = $pb.BuilderInfo( @@ -2347,7 +2433,8 @@ class ApplicationData extends $pb.GeneratedMessage { 27, 28, 29, - 30 + 30, + 31 ]) ..aOM(1, _omitFieldNames ? '' : 'textMessage', protoName: 'textMessage', @@ -2439,6 +2526,9 @@ class ApplicationData extends $pb.GeneratedMessage { ..aOM( 30, _omitFieldNames ? '' : 'setLoginToken', subBuilder: ApplicationData_SetLoginToken.create) + ..aOM( + 31, _omitFieldNames ? '' : 'registerPasswordlessRecovery', + subBuilder: ApplicationData_RegisterPasswordLessRecovery.create) ..hasRequiredFields = false; @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') @@ -2486,6 +2576,7 @@ class ApplicationData extends $pb.GeneratedMessage { @$pb.TagNumber(28) @$pb.TagNumber(29) @$pb.TagNumber(30) + @$pb.TagNumber(31) ApplicationData_ApplicationData whichApplicationData() => _ApplicationData_ApplicationDataByTag[$_whichOneof(0)]!; @$pb.TagNumber(1) @@ -2514,6 +2605,7 @@ class ApplicationData extends $pb.GeneratedMessage { @$pb.TagNumber(28) @$pb.TagNumber(29) @$pb.TagNumber(30) + @$pb.TagNumber(31) void clearApplicationData() => $_clearField($_whichOneof(0)); @$pb.TagNumber(1) @@ -2819,6 +2911,21 @@ class ApplicationData extends $pb.GeneratedMessage { void clearSetLoginToken() => $_clearField(30); @$pb.TagNumber(30) ApplicationData_SetLoginToken ensureSetLoginToken() => $_ensure(25); + + @$pb.TagNumber(31) + ApplicationData_RegisterPasswordLessRecovery + get registerPasswordlessRecovery => $_getN(26); + @$pb.TagNumber(31) + set registerPasswordlessRecovery( + ApplicationData_RegisterPasswordLessRecovery value) => + $_setField(31, value); + @$pb.TagNumber(31) + $core.bool hasRegisterPasswordlessRecovery() => $_has(26); + @$pb.TagNumber(31) + void clearRegisterPasswordlessRecovery() => $_clearField(31); + @$pb.TagNumber(31) + ApplicationData_RegisterPasswordLessRecovery + ensureRegisterPasswordlessRecovery() => $_ensure(26); } class Response_PreKey extends $pb.GeneratedMessage { diff --git a/lib/src/model/protobuf/api/websocket/client_to_server.pbjson.dart b/lib/src/model/protobuf/api/websocket/client_to_server.pbjson.dart index 9ea3c1f3..519efa17 100644 --- a/lib/src/model/protobuf/api/websocket/client_to_server.pbjson.dart +++ b/lib/src/model/protobuf/api/websocket/client_to_server.pbjson.dart @@ -575,6 +575,15 @@ const ApplicationData$json = { '9': 0, '10': 'setLoginToken' }, + { + '1': 'register_passwordless_recovery', + '3': 31, + '4': 1, + '5': 11, + '6': '.client_to_server.ApplicationData.RegisterPasswordLessRecovery', + '9': 0, + '10': 'registerPasswordlessRecovery' + }, ], '3': [ ApplicationData_TextMessage$json, @@ -596,7 +605,8 @@ const ApplicationData$json = { ApplicationData_DeleteAccount$json, ApplicationData_AddAdditionalUser$json, ApplicationData_SetLoginToken$json, - ApplicationData_Deprecated$json + ApplicationData_Deprecated$json, + ApplicationData_RegisterPasswordLessRecovery$json ], '8': [ {'1': 'ApplicationData'}, @@ -775,6 +785,35 @@ const ApplicationData_Deprecated$json = { '1': 'Deprecated', }; +@$core.Deprecated('Use applicationDataDescriptor instead') +const ApplicationData_RegisterPasswordLessRecovery$json = { + '1': 'RegisterPasswordLessRecovery', + '2': [ + { + '1': 'pinUnlockToken', + '3': 1, + '4': 1, + '5': 12, + '9': 0, + '10': 'pinUnlockToken', + '17': true + }, + { + '1': 'encryptedServerKey', + '3': 2, + '4': 1, + '5': 12, + '9': 1, + '10': 'encryptedServerKey', + '17': true + }, + ], + '8': [ + {'1': '_pinUnlockToken'}, + {'1': '_encryptedServerKey'}, + ], +}; + /// Descriptor for `ApplicationData`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List applicationDataDescriptor = $convert.base64Decode( 'Cg9BcHBsaWNhdGlvbkRhdGESUQoLdGV4dE1lc3NhZ2UYASABKAsyLS5jbGllbnRfdG9fc2Vydm' @@ -820,27 +859,32 @@ final $typed_data.Uint8List applicationDataDescriptor = $convert.base64Decode( 'dmVBZGRpdGlvbmFsVXNlchJjChFhZGRBZGRpdGlvbmFsVXNlchgdIAEoCzIzLmNsaWVudF90b1' '9zZXJ2ZXIuQXBwbGljYXRpb25EYXRhLkFkZEFkZGl0aW9uYWxVc2VySABSEWFkZEFkZGl0aW9u' 'YWxVc2VyElkKD3NldF9sb2dpbl90b2tlbhgeIAEoCzIvLmNsaWVudF90b19zZXJ2ZXIuQXBwbG' - 'ljYXRpb25EYXRhLlNldExvZ2luVG9rZW5IAFINc2V0TG9naW5Ub2tlbhpqCgtUZXh0TWVzc2Fn' - 'ZRIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQSEgoEYm9keRgDIAEoDFIEYm9keRIgCglwdXNoX2' - 'RhdGEYBCABKAxIAFIIcHVzaERhdGGIAQFCDAoKX3B1c2hfZGF0YRovChFHZXRVc2VyQnlVc2Vy' - 'bmFtZRIaCgh1c2VybmFtZRgBIAEoCVIIdXNlcm5hbWUaLAoOQ2hhbmdlVXNlcm5hbWUSGgoIdX' - 'Nlcm5hbWUYASABKAlSCHVzZXJuYW1lGjUKFFVwZGF0ZUdvb2dsZUZjbVRva2VuEh0KCmdvb2ds' - 'ZV9mY20YASABKAlSCWdvb2dsZUZjbRomCgtHZXRVc2VyQnlJZBIXCgd1c2VyX2lkGAEgASgDUg' - 'Z1c2VySWQaEwoRR2V0QXZhaWxhYmxlUGxhbnMaFwoVR2V0QWRkQWNjb3VudHNJbnZpdGVzGhUK' - 'E0dldEN1cnJlbnRQbGFuSW5mb3MaLwoUUmVtb3ZlQWRkaXRpb25hbFVzZXISFwoHdXNlcl9pZB' - 'gBIAEoA1IGdXNlcklkGi0KEkdldFByZWtleXNCeVVzZXJJZBIXCgd1c2VyX2lkGAEgASgDUgZ1' - 'c2VySWQaMgoXR2V0U2lnbmVkUHJlS2V5QnlVc2VySWQSFwoHdXNlcl9pZBgBIAEoA1IGdXNlck' - 'lkGpsBChJVcGRhdGVTaWduZWRQcmVLZXkSKAoQc2lnbmVkX3ByZWtleV9pZBgBIAEoA1IOc2ln' - 'bmVkUHJla2V5SWQSIwoNc2lnbmVkX3ByZWtleRgCIAEoDFIMc2lnbmVkUHJla2V5EjYKF3NpZ2' - '5lZF9wcmVrZXlfc2lnbmF0dXJlGAMgASgMUhVzaWduZWRQcmVrZXlTaWduYXR1cmUaNQoMRG93' - 'bmxvYWREb25lEiUKDmRvd25sb2FkX3Rva2VuGAEgASgMUg1kb3dubG9hZFRva2VuGk4KClJlcG' - '9ydFVzZXISKAoQcmVwb3J0ZWRfdXNlcl9pZBgBIAEoA1IOcmVwb3J0ZWRVc2VySWQSFgoGcmVh' - 'c29uGAIgASgJUgZyZWFzb24acQoLSVBBUHVyY2hhc2USHQoKcHJvZHVjdF9pZBgBIAEoCVIJcH' - 'JvZHVjdElkEhYKBnNvdXJjZRgCIAEoCVIGc291cmNlEisKEXZlcmlmaWNhdGlvbl9kYXRhGAMg' - 'ASgJUhB2ZXJpZmljYXRpb25EYXRhGg8KDUlQQUZvcmNlQ2hlY2saDwoNRGVsZXRlQWNjb3VudB' - 'osChFBZGRBZGRpdGlvbmFsVXNlchIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQaMAoNU2V0TG9n' - 'aW5Ub2tlbhIfCgtsb2dpbl90b2tlbhgBIAEoDFIKbG9naW5Ub2tlbhoMCgpEZXByZWNhdGVkQh' - 'EKD0FwcGxpY2F0aW9uRGF0YQ=='); + 'ljYXRpb25EYXRhLlNldExvZ2luVG9rZW5IAFINc2V0TG9naW5Ub2tlbhKGAQoecmVnaXN0ZXJf' + 'cGFzc3dvcmRsZXNzX3JlY292ZXJ5GB8gASgLMj4uY2xpZW50X3RvX3NlcnZlci5BcHBsaWNhdG' + 'lvbkRhdGEuUmVnaXN0ZXJQYXNzd29yZExlc3NSZWNvdmVyeUgAUhxyZWdpc3RlclBhc3N3b3Jk' + 'bGVzc1JlY292ZXJ5GmoKC1RleHRNZXNzYWdlEhcKB3VzZXJfaWQYASABKANSBnVzZXJJZBISCg' + 'Rib2R5GAMgASgMUgRib2R5EiAKCXB1c2hfZGF0YRgEIAEoDEgAUghwdXNoRGF0YYgBAUIMCgpf' + 'cHVzaF9kYXRhGi8KEUdldFVzZXJCeVVzZXJuYW1lEhoKCHVzZXJuYW1lGAEgASgJUgh1c2Vybm' + 'FtZRosCg5DaGFuZ2VVc2VybmFtZRIaCgh1c2VybmFtZRgBIAEoCVIIdXNlcm5hbWUaNQoUVXBk' + 'YXRlR29vZ2xlRmNtVG9rZW4SHQoKZ29vZ2xlX2ZjbRgBIAEoCVIJZ29vZ2xlRmNtGiYKC0dldF' + 'VzZXJCeUlkEhcKB3VzZXJfaWQYASABKANSBnVzZXJJZBoTChFHZXRBdmFpbGFibGVQbGFucxoX' + 'ChVHZXRBZGRBY2NvdW50c0ludml0ZXMaFQoTR2V0Q3VycmVudFBsYW5JbmZvcxovChRSZW1vdm' + 'VBZGRpdGlvbmFsVXNlchIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQaLQoSR2V0UHJla2V5c0J5' + 'VXNlcklkEhcKB3VzZXJfaWQYASABKANSBnVzZXJJZBoyChdHZXRTaWduZWRQcmVLZXlCeVVzZX' + 'JJZBIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQamwEKElVwZGF0ZVNpZ25lZFByZUtleRIoChBz' + 'aWduZWRfcHJla2V5X2lkGAEgASgDUg5zaWduZWRQcmVrZXlJZBIjCg1zaWduZWRfcHJla2V5GA' + 'IgASgMUgxzaWduZWRQcmVrZXkSNgoXc2lnbmVkX3ByZWtleV9zaWduYXR1cmUYAyABKAxSFXNp' + 'Z25lZFByZWtleVNpZ25hdHVyZRo1CgxEb3dubG9hZERvbmUSJQoOZG93bmxvYWRfdG9rZW4YAS' + 'ABKAxSDWRvd25sb2FkVG9rZW4aTgoKUmVwb3J0VXNlchIoChByZXBvcnRlZF91c2VyX2lkGAEg' + 'ASgDUg5yZXBvcnRlZFVzZXJJZBIWCgZyZWFzb24YAiABKAlSBnJlYXNvbhpxCgtJUEFQdXJjaG' + 'FzZRIdCgpwcm9kdWN0X2lkGAEgASgJUglwcm9kdWN0SWQSFgoGc291cmNlGAIgASgJUgZzb3Vy' + 'Y2USKwoRdmVyaWZpY2F0aW9uX2RhdGEYAyABKAlSEHZlcmlmaWNhdGlvbkRhdGEaDwoNSVBBRm' + '9yY2VDaGVjaxoPCg1EZWxldGVBY2NvdW50GiwKEUFkZEFkZGl0aW9uYWxVc2VyEhcKB3VzZXJf' + 'aWQYASABKANSBnVzZXJJZBowCg1TZXRMb2dpblRva2VuEh8KC2xvZ2luX3Rva2VuGAEgASgMUg' + 'psb2dpblRva2VuGgwKCkRlcHJlY2F0ZWQaqgEKHFJlZ2lzdGVyUGFzc3dvcmRMZXNzUmVjb3Zl' + 'cnkSKwoOcGluVW5sb2NrVG9rZW4YASABKAxIAFIOcGluVW5sb2NrVG9rZW6IAQESMwoSZW5jcn' + 'lwdGVkU2VydmVyS2V5GAIgASgMSAFSEmVuY3J5cHRlZFNlcnZlcktleYgBAUIRCg9fcGluVW5s' + 'b2NrVG9rZW5CFQoTX2VuY3J5cHRlZFNlcnZlcktleUIRCg9BcHBsaWNhdGlvbkRhdGE='); @$core.Deprecated('Use responseDescriptor instead') const Response$json = { diff --git a/lib/src/model/protobuf/client/generated/messages.pb.dart b/lib/src/model/protobuf/client/generated/messages.pb.dart index e805edfb..1680f4c8 100644 --- a/lib/src/model/protobuf/client/generated/messages.pb.dart +++ b/lib/src/model/protobuf/client/generated/messages.pb.dart @@ -1839,6 +1839,142 @@ class EncryptedContent_KeyVerificationProof extends $pb.GeneratedMessage { void clearCalculatedMac() => $_clearField(1); } +class EncryptedContent_PasswordLessRecovery extends $pb.GeneratedMessage { + factory EncryptedContent_PasswordLessRecovery({ + $core.List<$core.int>? recoverySecretShare, + $core.bool? delete, + }) { + final result = create(); + if (recoverySecretShare != null) + result.recoverySecretShare = recoverySecretShare; + if (delete != null) result.delete = delete; + return result; + } + + EncryptedContent_PasswordLessRecovery._(); + + factory EncryptedContent_PasswordLessRecovery.fromBuffer( + $core.List<$core.int> data, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(data, registry); + factory EncryptedContent_PasswordLessRecovery.fromJson($core.String json, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(json, registry); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'EncryptedContent.PasswordLessRecovery', + createEmptyInstance: create) + ..a<$core.List<$core.int>>( + 1, _omitFieldNames ? '' : 'recoverySecretShare', $pb.PbFieldType.OY, + protoName: 'recoverySecretShare') + ..aOB(2, _omitFieldNames ? '' : 'delete') + ..hasRequiredFields = false; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + EncryptedContent_PasswordLessRecovery clone() => deepCopy(); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + EncryptedContent_PasswordLessRecovery copyWith( + void Function(EncryptedContent_PasswordLessRecovery) updates) => + super.copyWith((message) => + updates(message as EncryptedContent_PasswordLessRecovery)) + as EncryptedContent_PasswordLessRecovery; + + @$core.override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static EncryptedContent_PasswordLessRecovery create() => + EncryptedContent_PasswordLessRecovery._(); + @$core.override + EncryptedContent_PasswordLessRecovery createEmptyInstance() => create(); + @$core.pragma('dart2js:noInline') + static EncryptedContent_PasswordLessRecovery getDefault() => + _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor< + EncryptedContent_PasswordLessRecovery>(create); + static EncryptedContent_PasswordLessRecovery? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get recoverySecretShare => $_getN(0); + @$pb.TagNumber(1) + set recoverySecretShare($core.List<$core.int> value) => $_setBytes(0, value); + @$pb.TagNumber(1) + $core.bool hasRecoverySecretShare() => $_has(0); + @$pb.TagNumber(1) + void clearRecoverySecretShare() => $_clearField(1); + + @$pb.TagNumber(2) + $core.bool get delete => $_getBF(1); + @$pb.TagNumber(2) + set delete($core.bool value) => $_setBool(1, value); + @$pb.TagNumber(2) + $core.bool hasDelete() => $_has(1); + @$pb.TagNumber(2) + void clearDelete() => $_clearField(2); +} + +class EncryptedContent_PasswordLessRecoveryHeartbeat + extends $pb.GeneratedMessage { + factory EncryptedContent_PasswordLessRecoveryHeartbeat({ + $core.List<$core.int>? hash, + }) { + final result = create(); + if (hash != null) result.hash = hash; + return result; + } + + EncryptedContent_PasswordLessRecoveryHeartbeat._(); + + factory EncryptedContent_PasswordLessRecoveryHeartbeat.fromBuffer( + $core.List<$core.int> data, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(data, registry); + factory EncryptedContent_PasswordLessRecoveryHeartbeat.fromJson( + $core.String json, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(json, registry); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'EncryptedContent.PasswordLessRecoveryHeartbeat', + createEmptyInstance: create) + ..a<$core.List<$core.int>>( + 1, _omitFieldNames ? '' : 'hash', $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + EncryptedContent_PasswordLessRecoveryHeartbeat clone() => deepCopy(); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + EncryptedContent_PasswordLessRecoveryHeartbeat copyWith( + void Function(EncryptedContent_PasswordLessRecoveryHeartbeat) + updates) => + super.copyWith((message) => updates( + message as EncryptedContent_PasswordLessRecoveryHeartbeat)) + as EncryptedContent_PasswordLessRecoveryHeartbeat; + + @$core.override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static EncryptedContent_PasswordLessRecoveryHeartbeat create() => + EncryptedContent_PasswordLessRecoveryHeartbeat._(); + @$core.override + EncryptedContent_PasswordLessRecoveryHeartbeat createEmptyInstance() => + create(); + @$core.pragma('dart2js:noInline') + static EncryptedContent_PasswordLessRecoveryHeartbeat getDefault() => + _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor< + EncryptedContent_PasswordLessRecoveryHeartbeat>(create); + static EncryptedContent_PasswordLessRecoveryHeartbeat? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get hash => $_getN(0); + @$pb.TagNumber(1) + set hash($core.List<$core.int> value) => $_setBytes(0, value); + @$pb.TagNumber(1) + $core.bool hasHash() => $_has(0); + @$pb.TagNumber(1) + void clearHash() => $_clearField(1); +} + class EncryptedContent extends $pb.GeneratedMessage { factory EncryptedContent({ $core.String? groupId, @@ -1865,6 +2001,9 @@ class EncryptedContent extends $pb.GeneratedMessage { EncryptedContent_UserDiscoveryUpdate? userDiscoveryUpdate, EncryptedContent_KeyVerificationProof? keyVerificationProof, $core.bool? askForFriendPromotions, + EncryptedContent_PasswordLessRecovery? passwordlessRecovery, + EncryptedContent_PasswordLessRecoveryHeartbeat? + passwordlessRecoveryHeartbeat, }) { final result = create(); if (groupId != null) result.groupId = groupId; @@ -1899,6 +2038,10 @@ class EncryptedContent extends $pb.GeneratedMessage { result.keyVerificationProof = keyVerificationProof; if (askForFriendPromotions != null) result.askForFriendPromotions = askForFriendPromotions; + if (passwordlessRecovery != null) + result.passwordlessRecovery = passwordlessRecovery; + if (passwordlessRecoveryHeartbeat != null) + result.passwordlessRecoveryHeartbeat = passwordlessRecoveryHeartbeat; return result; } @@ -1971,6 +2114,12 @@ class EncryptedContent extends $pb.GeneratedMessage { 24, _omitFieldNames ? '' : 'keyVerificationProof', subBuilder: EncryptedContent_KeyVerificationProof.create) ..aOB(25, _omitFieldNames ? '' : 'askForFriendPromotions') + ..aOM( + 26, _omitFieldNames ? '' : 'passwordlessRecovery', + subBuilder: EncryptedContent_PasswordLessRecovery.create) + ..aOM( + 27, _omitFieldNames ? '' : 'passwordlessRecoveryHeartbeat', + subBuilder: EncryptedContent_PasswordLessRecoveryHeartbeat.create) ..hasRequiredFields = false; @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') @@ -2263,6 +2412,34 @@ class EncryptedContent extends $pb.GeneratedMessage { $core.bool hasAskForFriendPromotions() => $_has(23); @$pb.TagNumber(25) void clearAskForFriendPromotions() => $_clearField(25); + + @$pb.TagNumber(26) + EncryptedContent_PasswordLessRecovery get passwordlessRecovery => $_getN(24); + @$pb.TagNumber(26) + set passwordlessRecovery(EncryptedContent_PasswordLessRecovery value) => + $_setField(26, value); + @$pb.TagNumber(26) + $core.bool hasPasswordlessRecovery() => $_has(24); + @$pb.TagNumber(26) + void clearPasswordlessRecovery() => $_clearField(26); + @$pb.TagNumber(26) + EncryptedContent_PasswordLessRecovery ensurePasswordlessRecovery() => + $_ensure(24); + + @$pb.TagNumber(27) + EncryptedContent_PasswordLessRecoveryHeartbeat + get passwordlessRecoveryHeartbeat => $_getN(25); + @$pb.TagNumber(27) + set passwordlessRecoveryHeartbeat( + EncryptedContent_PasswordLessRecoveryHeartbeat value) => + $_setField(27, value); + @$pb.TagNumber(27) + $core.bool hasPasswordlessRecoveryHeartbeat() => $_has(25); + @$pb.TagNumber(27) + void clearPasswordlessRecoveryHeartbeat() => $_clearField(27); + @$pb.TagNumber(27) + EncryptedContent_PasswordLessRecoveryHeartbeat + ensurePasswordlessRecoveryHeartbeat() => $_ensure(25); } const $core.bool _omitFieldNames = diff --git a/lib/src/model/protobuf/client/generated/messages.pbjson.dart b/lib/src/model/protobuf/client/generated/messages.pbjson.dart index 96f73817..c993de4e 100644 --- a/lib/src/model/protobuf/client/generated/messages.pbjson.dart +++ b/lib/src/model/protobuf/client/generated/messages.pbjson.dart @@ -385,6 +385,26 @@ const EncryptedContent$json = { '10': 'keyVerificationProof', '17': true }, + { + '1': 'passwordless_recovery', + '3': 26, + '4': 1, + '5': 11, + '6': '.EncryptedContent.PasswordLessRecovery', + '9': 24, + '10': 'passwordlessRecovery', + '17': true + }, + { + '1': 'passwordless_recovery_heartbeat', + '3': 27, + '4': 1, + '5': 11, + '6': '.EncryptedContent.PasswordLessRecoveryHeartbeat', + '9': 25, + '10': 'passwordlessRecoveryHeartbeat', + '17': true + }, ], '3': [ EncryptedContent_ErrorMessages$json, @@ -405,7 +425,9 @@ const EncryptedContent$json = { EncryptedContent_TypingIndicator$json, EncryptedContent_UserDiscoveryRequest$json, EncryptedContent_UserDiscoveryUpdate$json, - EncryptedContent_KeyVerificationProof$json + EncryptedContent_KeyVerificationProof$json, + EncryptedContent_PasswordLessRecovery$json, + EncryptedContent_PasswordLessRecoveryHeartbeat$json ], '8': [ {'1': '_group_id'}, @@ -432,6 +454,8 @@ const EncryptedContent$json = { {'1': '_user_discovery_request'}, {'1': '_user_discovery_update'}, {'1': '_key_verification_proof'}, + {'1': '_passwordless_recovery'}, + {'1': '_passwordless_recovery_heartbeat'}, ], }; @@ -955,6 +979,34 @@ const EncryptedContent_KeyVerificationProof$json = { ], }; +@$core.Deprecated('Use encryptedContentDescriptor instead') +const EncryptedContent_PasswordLessRecovery$json = { + '1': 'PasswordLessRecovery', + '2': [ + { + '1': 'recoverySecretShare', + '3': 1, + '4': 1, + '5': 12, + '9': 0, + '10': 'recoverySecretShare', + '17': true + }, + {'1': 'delete', '3': 2, '4': 1, '5': 8, '10': 'delete'}, + ], + '8': [ + {'1': '_recoverySecretShare'}, + ], +}; + +@$core.Deprecated('Use encryptedContentDescriptor instead') +const EncryptedContent_PasswordLessRecoveryHeartbeat$json = { + '1': 'PasswordLessRecoveryHeartbeat', + '2': [ + {'1': 'hash', '3': 1, '4': 1, '5': 12, '10': 'hash'}, + ], +}; + /// Descriptor for `EncryptedContent`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List encryptedContentDescriptor = $convert.base64Decode( 'ChBFbmNyeXB0ZWRDb250ZW50Eh4KCGdyb3VwX2lkGAIgASgJSABSB2dyb3VwSWSIAQESKQoOaX' @@ -988,79 +1040,88 @@ final $typed_data.Uint8List encryptedContentDescriptor = $convert.base64Decode( 'aXNjb3ZlcnlSZXF1ZXN0iAEBEl4KFXVzZXJfZGlzY292ZXJ5X3VwZGF0ZRgXIAEoCzIlLkVuY3' 'J5cHRlZENvbnRlbnQuVXNlckRpc2NvdmVyeVVwZGF0ZUgWUhN1c2VyRGlzY292ZXJ5VXBkYXRl' 'iAEBEmEKFmtleV92ZXJpZmljYXRpb25fcHJvb2YYGCABKAsyJi5FbmNyeXB0ZWRDb250ZW50Lk' - 'tleVZlcmlmaWNhdGlvblByb29mSBdSFGtleVZlcmlmaWNhdGlvblByb29miAEBGpYCCg1FcnJv' - 'ck1lc3NhZ2VzEjgKBHR5cGUYASABKA4yJC5FbmNyeXB0ZWRDb250ZW50LkVycm9yTWVzc2FnZX' - 'MuVHlwZVIEdHlwZRIsChJyZWxhdGVkX3JlY2VpcHRfaWQYAiABKAlSEHJlbGF0ZWRSZWNlaXB0' - 'SWQinAEKBFR5cGUSPAo4RVJST1JfUFJPQ0VTU0lOR19NRVNTQUdFX0NSRUFURURfQUNDT1VOVF' - '9SRVFVRVNUX0lOU1RFQUQQABIYChRVTktOT1dOX01FU1NBR0VfVFlQRRACEhcKE1NFU1NJT05f' - 'T1VUX09GX1NZTkMQAxIjCh9HUk9VUF9OT1RfRk9VTkRfT1JfTk9UX0FfTUVNQkVSEAQahwEKC0' - 'dyb3VwQ3JlYXRlEhsKCXN0YXRlX2tleRgDIAEoDFIIc3RhdGVLZXkSKAoQZ3JvdXBfcHVibGlj' - 'X2tleRgEIAEoDFIOZ3JvdXBQdWJsaWNLZXkSIgoKZ3JvdXBfbmFtZRgFIAEoCUgAUglncm91cE' - '5hbWWIAQFCDQoLX2dyb3VwX25hbWUaNQoJR3JvdXBKb2luEigKEGdyb3VwX3B1YmxpY19rZXkY' - 'ASABKAxSDmdyb3VwUHVibGljS2V5GhYKFFJlc2VuZEdyb3VwUHVibGljS2V5GsgCCgtHcm91cF' - 'VwZGF0ZRIqChFncm91cF9hY3Rpb25fdHlwZRgBIAEoCVIPZ3JvdXBBY3Rpb25UeXBlEjMKE2Fm' - 'ZmVjdGVkX2NvbnRhY3RfaWQYAiABKANIAFIRYWZmZWN0ZWRDb250YWN0SWSIAQESKQoObmV3X2' - 'dyb3VwX25hbWUYAyABKAlIAVIMbmV3R3JvdXBOYW1liAEBElcKJm5ld19kZWxldGVfbWVzc2Fn' - 'ZXNfYWZ0ZXJfbWlsbGlzZWNvbmRzGAQgASgDSAJSIm5ld0RlbGV0ZU1lc3NhZ2VzQWZ0ZXJNaW' - 'xsaXNlY29uZHOIAQFCFgoUX2FmZmVjdGVkX2NvbnRhY3RfaWRCEQoPX25ld19ncm91cF9uYW1l' - 'QikKJ19uZXdfZGVsZXRlX21lc3NhZ2VzX2FmdGVyX21pbGxpc2Vjb25kcxqvAQoLVGV4dE1lc3' - 'NhZ2USKgoRc2VuZGVyX21lc3NhZ2VfaWQYASABKAlSD3NlbmRlck1lc3NhZ2VJZBISCgR0ZXh0' - 'GAIgASgJUgR0ZXh0EhwKCXRpbWVzdGFtcBgDIAEoA1IJdGltZXN0YW1wEi0KEHF1b3RlX21lc3' - 'NhZ2VfaWQYBCABKAlIAFIOcXVvdGVNZXNzYWdlSWSIAQFCEwoRX3F1b3RlX21lc3NhZ2VfaWQa' - 'zgEKFUFkZGl0aW9uYWxEYXRhTWVzc2FnZRIqChFzZW5kZXJfbWVzc2FnZV9pZBgBIAEoCVIPc2' - 'VuZGVyTWVzc2FnZUlkEhwKCXRpbWVzdGFtcBgCIAEoA1IJdGltZXN0YW1wEhIKBHR5cGUYAyAB' - 'KAlSBHR5cGUSOwoXYWRkaXRpb25hbF9tZXNzYWdlX2RhdGEYBCABKAxIAFIVYWRkaXRpb25hbE' - '1lc3NhZ2VEYXRhiAEBQhoKGF9hZGRpdGlvbmFsX21lc3NhZ2VfZGF0YRpkCghSZWFjdGlvbhIq' - 'ChF0YXJnZXRfbWVzc2FnZV9pZBgBIAEoCVIPdGFyZ2V0TWVzc2FnZUlkEhQKBWVtb2ppGAIgAS' - 'gJUgVlbW9qaRIWCgZyZW1vdmUYAyABKAhSBnJlbW92ZRq+AgoNTWVzc2FnZVVwZGF0ZRI4CgR0' - 'eXBlGAEgASgOMiQuRW5jcnlwdGVkQ29udGVudC5NZXNzYWdlVXBkYXRlLlR5cGVSBHR5cGUSLw' - 'oRc2VuZGVyX21lc3NhZ2VfaWQYAiABKAlIAFIPc2VuZGVyTWVzc2FnZUlkiAEBEj0KG211bHRp' - 'cGxlX3RhcmdldF9tZXNzYWdlX2lkcxgDIAMoCVIYbXVsdGlwbGVUYXJnZXRNZXNzYWdlSWRzEh' - 'cKBHRleHQYBCABKAlIAVIEdGV4dIgBARIcCgl0aW1lc3RhbXAYBSABKANSCXRpbWVzdGFtcCIt' - 'CgRUeXBlEgoKBkRFTEVURRAAEg0KCUVESVRfVEVYVBABEgoKBk9QRU5FRBACQhQKEl9zZW5kZX' - 'JfbWVzc2FnZV9pZEIHCgVfdGV4dBqFBgoFTWVkaWESKgoRc2VuZGVyX21lc3NhZ2VfaWQYASAB' - 'KAlSD3NlbmRlck1lc3NhZ2VJZBIwCgR0eXBlGAIgASgOMhwuRW5jcnlwdGVkQ29udGVudC5NZW' - 'RpYS5UeXBlUgR0eXBlEkYKHWRpc3BsYXlfbGltaXRfaW5fbWlsbGlzZWNvbmRzGAMgASgDSABS' - 'GmRpc3BsYXlMaW1pdEluTWlsbGlzZWNvbmRziAEBEjcKF3JlcXVpcmVzX2F1dGhlbnRpY2F0aW' - '9uGAQgASgIUhZyZXF1aXJlc0F1dGhlbnRpY2F0aW9uEhwKCXRpbWVzdGFtcBgFIAEoA1IJdGlt' - 'ZXN0YW1wEi0KEHF1b3RlX21lc3NhZ2VfaWQYBiABKAlIAVIOcXVvdGVNZXNzYWdlSWSIAQESKg' - 'oOZG93bmxvYWRfdG9rZW4YByABKAxIAlINZG93bmxvYWRUb2tlbogBARIqCg5lbmNyeXB0aW9u' - 'X2tleRgIIAEoDEgDUg1lbmNyeXB0aW9uS2V5iAEBEioKDmVuY3J5cHRpb25fbWFjGAkgASgMSA' - 'RSDWVuY3J5cHRpb25NYWOIAQESLgoQZW5jcnlwdGlvbl9ub25jZRgKIAEoDEgFUg9lbmNyeXB0' - 'aW9uTm9uY2WIAQESOwoXYWRkaXRpb25hbF9tZXNzYWdlX2RhdGEYCyABKAxIBlIVYWRkaXRpb2' - '5hbE1lc3NhZ2VEYXRhiAEBIj4KBFR5cGUSDAoIUkVVUExPQUQQABIJCgVJTUFHRRABEgkKBVZJ' - 'REVPEAISBwoDR0lGEAMSCQoFQVVESU8QBEIgCh5fZGlzcGxheV9saW1pdF9pbl9taWxsaXNlY2' - '9uZHNCEwoRX3F1b3RlX21lc3NhZ2VfaWRCEQoPX2Rvd25sb2FkX3Rva2VuQhEKD19lbmNyeXB0' - 'aW9uX2tleUIRCg9fZW5jcnlwdGlvbl9tYWNCEwoRX2VuY3J5cHRpb25fbm9uY2VCGgoYX2FkZG' - 'l0aW9uYWxfbWVzc2FnZV9kYXRhGqkBCgtNZWRpYVVwZGF0ZRI2CgR0eXBlGAEgASgOMiIuRW5j' - 'cnlwdGVkQ29udGVudC5NZWRpYVVwZGF0ZS5UeXBlUgR0eXBlEioKEXRhcmdldF9tZXNzYWdlX2' - 'lkGAIgASgJUg90YXJnZXRNZXNzYWdlSWQiNgoEVHlwZRIMCghSRU9QRU5FRBAAEgoKBlNUT1JF' - 'RBABEhQKEERFQ1JZUFRJT05fRVJST1IQAhp4Cg5Db250YWN0UmVxdWVzdBI5CgR0eXBlGAEgAS' - 'gOMiUuRW5jcnlwdGVkQ29udGVudC5Db250YWN0UmVxdWVzdC5UeXBlUgR0eXBlIisKBFR5cGUS' - 'CwoHUkVRVUVTVBAAEgoKBlJFSkVDVBABEgoKBkFDQ0VQVBACGqQCCg1Db250YWN0VXBkYXRlEj' - 'gKBHR5cGUYASABKA4yJC5FbmNyeXB0ZWRDb250ZW50LkNvbnRhY3RVcGRhdGUuVHlwZVIEdHlw' - 'ZRI3ChVhdmF0YXJfc3ZnX2NvbXByZXNzZWQYAiABKAxIAFITYXZhdGFyU3ZnQ29tcHJlc3NlZI' - 'gBARIfCgh1c2VybmFtZRgDIAEoCUgBUgh1c2VybmFtZYgBARImCgxkaXNwbGF5X25hbWUYBCAB' - 'KAlIAlILZGlzcGxheU5hbWWIAQEiHwoEVHlwZRILCgdSRVFVRVNUEAASCgoGVVBEQVRFEAFCGA' - 'oWX2F2YXRhcl9zdmdfY29tcHJlc3NlZEILCglfdXNlcm5hbWVCDwoNX2Rpc3BsYXlfbmFtZRrZ' - 'AQoIUHVzaEtleXMSMwoEdHlwZRgBIAEoDjIfLkVuY3J5cHRlZENvbnRlbnQuUHVzaEtleXMuVH' - 'lwZVIEdHlwZRIaCgZrZXlfaWQYAiABKANIAFIFa2V5SWSIAQESFQoDa2V5GAMgASgMSAFSA2tl' - 'eYgBARIiCgpjcmVhdGVkX2F0GAQgASgDSAJSCWNyZWF0ZWRBdIgBASIfCgRUeXBlEgsKB1JFUV' - 'VFU1QQABIKCgZVUERBVEUQAUIJCgdfa2V5X2lkQgYKBF9rZXlCDQoLX2NyZWF0ZWRfYXQarwEK' - 'CUZsYW1lU3luYxIjCg1mbGFtZV9jb3VudGVyGAEgASgDUgxmbGFtZUNvdW50ZXISOQoZbGFzdF' - '9mbGFtZV9jb3VudGVyX2NoYW5nZRgCIAEoA1IWbGFzdEZsYW1lQ291bnRlckNoYW5nZRIfCgti' - 'ZXN0X2ZyaWVuZBgDIAEoCFIKYmVzdEZyaWVuZBIhCgxmb3JjZV91cGRhdGUYBCABKAhSC2Zvcm' - 'NlVXBkYXRlGk0KD1R5cGluZ0luZGljYXRvchIbCglpc190eXBpbmcYASABKAhSCGlzVHlwaW5n' - 'Eh0KCmNyZWF0ZWRfYXQYAiABKANSCWNyZWF0ZWRBdBo/ChRVc2VyRGlzY292ZXJ5UmVxdWVzdB' - 'InCg9jdXJyZW50X3ZlcnNpb24YASABKAxSDmN1cnJlbnRWZXJzaW9uGjEKE1VzZXJEaXNjb3Zl' - 'cnlVcGRhdGUSGgoIbWVzc2FnZXMYASADKAxSCG1lc3NhZ2VzGj0KFEtleVZlcmlmaWNhdGlvbl' - 'Byb29mEiUKDmNhbGN1bGF0ZWRfbWFjGAEgASgMUg1jYWxjdWxhdGVkTWFjQgsKCV9ncm91cF9p' - 'ZEIRCg9faXNfZGlyZWN0X2NoYXRCGQoXX3NlbmRlcl9wcm9maWxlX2NvdW50ZXJCIAoeX3Nlbm' - 'Rlcl91c2VyX2Rpc2NvdmVyeV92ZXJzaW9uQhwKGl9hc2tfZm9yX2ZyaWVuZF9wcm9tb3Rpb25z' - 'QhEKD19tZXNzYWdlX3VwZGF0ZUIICgZfbWVkaWFCDwoNX21lZGlhX3VwZGF0ZUIRCg9fY29udG' - 'FjdF91cGRhdGVCEgoQX2NvbnRhY3RfcmVxdWVzdEINCgtfZmxhbWVfc3luY0IMCgpfcHVzaF9r' - 'ZXlzQgsKCV9yZWFjdGlvbkIPCg1fdGV4dF9tZXNzYWdlQg8KDV9ncm91cF9jcmVhdGVCDQoLX2' - 'dyb3VwX2pvaW5CDwoNX2dyb3VwX3VwZGF0ZUIaChhfcmVzZW5kX2dyb3VwX3B1YmxpY19rZXlC' - 'EQoPX2Vycm9yX21lc3NhZ2VzQhoKGF9hZGRpdGlvbmFsX2RhdGFfbWVzc2FnZUITChFfdHlwaW' - '5nX2luZGljYXRvckIZChdfdXNlcl9kaXNjb3ZlcnlfcmVxdWVzdEIYChZfdXNlcl9kaXNjb3Zl' - 'cnlfdXBkYXRlQhkKF19rZXlfdmVyaWZpY2F0aW9uX3Byb29m'); + 'tleVZlcmlmaWNhdGlvblByb29mSBdSFGtleVZlcmlmaWNhdGlvblByb29miAEBEmAKFXBhc3N3' + 'b3JkbGVzc19yZWNvdmVyeRgaIAEoCzImLkVuY3J5cHRlZENvbnRlbnQuUGFzc3dvcmRMZXNzUm' + 'Vjb3ZlcnlIGFIUcGFzc3dvcmRsZXNzUmVjb3ZlcnmIAQESfAofcGFzc3dvcmRsZXNzX3JlY292' + 'ZXJ5X2hlYXJ0YmVhdBgbIAEoCzIvLkVuY3J5cHRlZENvbnRlbnQuUGFzc3dvcmRMZXNzUmVjb3' + 'ZlcnlIZWFydGJlYXRIGVIdcGFzc3dvcmRsZXNzUmVjb3ZlcnlIZWFydGJlYXSIAQEalgIKDUVy' + 'cm9yTWVzc2FnZXMSOAoEdHlwZRgBIAEoDjIkLkVuY3J5cHRlZENvbnRlbnQuRXJyb3JNZXNzYW' + 'dlcy5UeXBlUgR0eXBlEiwKEnJlbGF0ZWRfcmVjZWlwdF9pZBgCIAEoCVIQcmVsYXRlZFJlY2Vp' + 'cHRJZCKcAQoEVHlwZRI8CjhFUlJPUl9QUk9DRVNTSU5HX01FU1NBR0VfQ1JFQVRFRF9BQ0NPVU' + '5UX1JFUVVFU1RfSU5TVEVBRBAAEhgKFFVOS05PV05fTUVTU0FHRV9UWVBFEAISFwoTU0VTU0lP' + 'Tl9PVVRfT0ZfU1lOQxADEiMKH0dST1VQX05PVF9GT1VORF9PUl9OT1RfQV9NRU1CRVIQBBqHAQ' + 'oLR3JvdXBDcmVhdGUSGwoJc3RhdGVfa2V5GAMgASgMUghzdGF0ZUtleRIoChBncm91cF9wdWJs' + 'aWNfa2V5GAQgASgMUg5ncm91cFB1YmxpY0tleRIiCgpncm91cF9uYW1lGAUgASgJSABSCWdyb3' + 'VwTmFtZYgBAUINCgtfZ3JvdXBfbmFtZRo1CglHcm91cEpvaW4SKAoQZ3JvdXBfcHVibGljX2tl' + 'eRgBIAEoDFIOZ3JvdXBQdWJsaWNLZXkaFgoUUmVzZW5kR3JvdXBQdWJsaWNLZXkayAIKC0dyb3' + 'VwVXBkYXRlEioKEWdyb3VwX2FjdGlvbl90eXBlGAEgASgJUg9ncm91cEFjdGlvblR5cGUSMwoT' + 'YWZmZWN0ZWRfY29udGFjdF9pZBgCIAEoA0gAUhFhZmZlY3RlZENvbnRhY3RJZIgBARIpCg5uZX' + 'dfZ3JvdXBfbmFtZRgDIAEoCUgBUgxuZXdHcm91cE5hbWWIAQESVwombmV3X2RlbGV0ZV9tZXNz' + 'YWdlc19hZnRlcl9taWxsaXNlY29uZHMYBCABKANIAlIibmV3RGVsZXRlTWVzc2FnZXNBZnRlck' + '1pbGxpc2Vjb25kc4gBAUIWChRfYWZmZWN0ZWRfY29udGFjdF9pZEIRCg9fbmV3X2dyb3VwX25h' + 'bWVCKQonX25ld19kZWxldGVfbWVzc2FnZXNfYWZ0ZXJfbWlsbGlzZWNvbmRzGq8BCgtUZXh0TW' + 'Vzc2FnZRIqChFzZW5kZXJfbWVzc2FnZV9pZBgBIAEoCVIPc2VuZGVyTWVzc2FnZUlkEhIKBHRl' + 'eHQYAiABKAlSBHRleHQSHAoJdGltZXN0YW1wGAMgASgDUgl0aW1lc3RhbXASLQoQcXVvdGVfbW' + 'Vzc2FnZV9pZBgEIAEoCUgAUg5xdW90ZU1lc3NhZ2VJZIgBAUITChFfcXVvdGVfbWVzc2FnZV9p' + 'ZBrOAQoVQWRkaXRpb25hbERhdGFNZXNzYWdlEioKEXNlbmRlcl9tZXNzYWdlX2lkGAEgASgJUg' + '9zZW5kZXJNZXNzYWdlSWQSHAoJdGltZXN0YW1wGAIgASgDUgl0aW1lc3RhbXASEgoEdHlwZRgD' + 'IAEoCVIEdHlwZRI7ChdhZGRpdGlvbmFsX21lc3NhZ2VfZGF0YRgEIAEoDEgAUhVhZGRpdGlvbm' + 'FsTWVzc2FnZURhdGGIAQFCGgoYX2FkZGl0aW9uYWxfbWVzc2FnZV9kYXRhGmQKCFJlYWN0aW9u' + 'EioKEXRhcmdldF9tZXNzYWdlX2lkGAEgASgJUg90YXJnZXRNZXNzYWdlSWQSFAoFZW1vamkYAi' + 'ABKAlSBWVtb2ppEhYKBnJlbW92ZRgDIAEoCFIGcmVtb3ZlGr4CCg1NZXNzYWdlVXBkYXRlEjgK' + 'BHR5cGUYASABKA4yJC5FbmNyeXB0ZWRDb250ZW50Lk1lc3NhZ2VVcGRhdGUuVHlwZVIEdHlwZR' + 'IvChFzZW5kZXJfbWVzc2FnZV9pZBgCIAEoCUgAUg9zZW5kZXJNZXNzYWdlSWSIAQESPQobbXVs' + 'dGlwbGVfdGFyZ2V0X21lc3NhZ2VfaWRzGAMgAygJUhhtdWx0aXBsZVRhcmdldE1lc3NhZ2VJZH' + 'MSFwoEdGV4dBgEIAEoCUgBUgR0ZXh0iAEBEhwKCXRpbWVzdGFtcBgFIAEoA1IJdGltZXN0YW1w' + 'Ii0KBFR5cGUSCgoGREVMRVRFEAASDQoJRURJVF9URVhUEAESCgoGT1BFTkVEEAJCFAoSX3Nlbm' + 'Rlcl9tZXNzYWdlX2lkQgcKBV90ZXh0GoUGCgVNZWRpYRIqChFzZW5kZXJfbWVzc2FnZV9pZBgB' + 'IAEoCVIPc2VuZGVyTWVzc2FnZUlkEjAKBHR5cGUYAiABKA4yHC5FbmNyeXB0ZWRDb250ZW50Lk' + '1lZGlhLlR5cGVSBHR5cGUSRgodZGlzcGxheV9saW1pdF9pbl9taWxsaXNlY29uZHMYAyABKANI' + 'AFIaZGlzcGxheUxpbWl0SW5NaWxsaXNlY29uZHOIAQESNwoXcmVxdWlyZXNfYXV0aGVudGljYX' + 'Rpb24YBCABKAhSFnJlcXVpcmVzQXV0aGVudGljYXRpb24SHAoJdGltZXN0YW1wGAUgASgDUgl0' + 'aW1lc3RhbXASLQoQcXVvdGVfbWVzc2FnZV9pZBgGIAEoCUgBUg5xdW90ZU1lc3NhZ2VJZIgBAR' + 'IqCg5kb3dubG9hZF90b2tlbhgHIAEoDEgCUg1kb3dubG9hZFRva2VuiAEBEioKDmVuY3J5cHRp' + 'b25fa2V5GAggASgMSANSDWVuY3J5cHRpb25LZXmIAQESKgoOZW5jcnlwdGlvbl9tYWMYCSABKA' + 'xIBFINZW5jcnlwdGlvbk1hY4gBARIuChBlbmNyeXB0aW9uX25vbmNlGAogASgMSAVSD2VuY3J5' + 'cHRpb25Ob25jZYgBARI7ChdhZGRpdGlvbmFsX21lc3NhZ2VfZGF0YRgLIAEoDEgGUhVhZGRpdG' + 'lvbmFsTWVzc2FnZURhdGGIAQEiPgoEVHlwZRIMCghSRVVQTE9BRBAAEgkKBUlNQUdFEAESCQoF' + 'VklERU8QAhIHCgNHSUYQAxIJCgVBVURJTxAEQiAKHl9kaXNwbGF5X2xpbWl0X2luX21pbGxpc2' + 'Vjb25kc0ITChFfcXVvdGVfbWVzc2FnZV9pZEIRCg9fZG93bmxvYWRfdG9rZW5CEQoPX2VuY3J5' + 'cHRpb25fa2V5QhEKD19lbmNyeXB0aW9uX21hY0ITChFfZW5jcnlwdGlvbl9ub25jZUIaChhfYW' + 'RkaXRpb25hbF9tZXNzYWdlX2RhdGEaqQEKC01lZGlhVXBkYXRlEjYKBHR5cGUYASABKA4yIi5F' + 'bmNyeXB0ZWRDb250ZW50Lk1lZGlhVXBkYXRlLlR5cGVSBHR5cGUSKgoRdGFyZ2V0X21lc3NhZ2' + 'VfaWQYAiABKAlSD3RhcmdldE1lc3NhZ2VJZCI2CgRUeXBlEgwKCFJFT1BFTkVEEAASCgoGU1RP' + 'UkVEEAESFAoQREVDUllQVElPTl9FUlJPUhACGngKDkNvbnRhY3RSZXF1ZXN0EjkKBHR5cGUYAS' + 'ABKA4yJS5FbmNyeXB0ZWRDb250ZW50LkNvbnRhY3RSZXF1ZXN0LlR5cGVSBHR5cGUiKwoEVHlw' + 'ZRILCgdSRVFVRVNUEAASCgoGUkVKRUNUEAESCgoGQUNDRVBUEAIapAIKDUNvbnRhY3RVcGRhdG' + 'USOAoEdHlwZRgBIAEoDjIkLkVuY3J5cHRlZENvbnRlbnQuQ29udGFjdFVwZGF0ZS5UeXBlUgR0' + 'eXBlEjcKFWF2YXRhcl9zdmdfY29tcHJlc3NlZBgCIAEoDEgAUhNhdmF0YXJTdmdDb21wcmVzc2' + 'VkiAEBEh8KCHVzZXJuYW1lGAMgASgJSAFSCHVzZXJuYW1liAEBEiYKDGRpc3BsYXlfbmFtZRgE' + 'IAEoCUgCUgtkaXNwbGF5TmFtZYgBASIfCgRUeXBlEgsKB1JFUVVFU1QQABIKCgZVUERBVEUQAU' + 'IYChZfYXZhdGFyX3N2Z19jb21wcmVzc2VkQgsKCV91c2VybmFtZUIPCg1fZGlzcGxheV9uYW1l' + 'GtkBCghQdXNoS2V5cxIzCgR0eXBlGAEgASgOMh8uRW5jcnlwdGVkQ29udGVudC5QdXNoS2V5cy' + '5UeXBlUgR0eXBlEhoKBmtleV9pZBgCIAEoA0gAUgVrZXlJZIgBARIVCgNrZXkYAyABKAxIAVID' + 'a2V5iAEBEiIKCmNyZWF0ZWRfYXQYBCABKANIAlIJY3JlYXRlZEF0iAEBIh8KBFR5cGUSCwoHUk' + 'VRVUVTVBAAEgoKBlVQREFURRABQgkKB19rZXlfaWRCBgoEX2tleUINCgtfY3JlYXRlZF9hdBqv' + 'AQoJRmxhbWVTeW5jEiMKDWZsYW1lX2NvdW50ZXIYASABKANSDGZsYW1lQ291bnRlchI5ChlsYX' + 'N0X2ZsYW1lX2NvdW50ZXJfY2hhbmdlGAIgASgDUhZsYXN0RmxhbWVDb3VudGVyQ2hhbmdlEh8K' + 'C2Jlc3RfZnJpZW5kGAMgASgIUgpiZXN0RnJpZW5kEiEKDGZvcmNlX3VwZGF0ZRgEIAEoCFILZm' + '9yY2VVcGRhdGUaTQoPVHlwaW5nSW5kaWNhdG9yEhsKCWlzX3R5cGluZxgBIAEoCFIIaXNUeXBp' + 'bmcSHQoKY3JlYXRlZF9hdBgCIAEoA1IJY3JlYXRlZEF0Gj8KFFVzZXJEaXNjb3ZlcnlSZXF1ZX' + 'N0EicKD2N1cnJlbnRfdmVyc2lvbhgBIAEoDFIOY3VycmVudFZlcnNpb24aMQoTVXNlckRpc2Nv' + 'dmVyeVVwZGF0ZRIaCghtZXNzYWdlcxgBIAMoDFIIbWVzc2FnZXMaPQoUS2V5VmVyaWZpY2F0aW' + '9uUHJvb2YSJQoOY2FsY3VsYXRlZF9tYWMYASABKAxSDWNhbGN1bGF0ZWRNYWMafQoUUGFzc3dv' + 'cmRMZXNzUmVjb3ZlcnkSNQoTcmVjb3ZlcnlTZWNyZXRTaGFyZRgBIAEoDEgAUhNyZWNvdmVyeV' + 'NlY3JldFNoYXJliAEBEhYKBmRlbGV0ZRgCIAEoCFIGZGVsZXRlQhYKFF9yZWNvdmVyeVNlY3Jl' + 'dFNoYXJlGjMKHVBhc3N3b3JkTGVzc1JlY292ZXJ5SGVhcnRiZWF0EhIKBGhhc2gYASABKAxSBG' + 'hhc2hCCwoJX2dyb3VwX2lkQhEKD19pc19kaXJlY3RfY2hhdEIZChdfc2VuZGVyX3Byb2ZpbGVf' + 'Y291bnRlckIgCh5fc2VuZGVyX3VzZXJfZGlzY292ZXJ5X3ZlcnNpb25CHAoaX2Fza19mb3JfZn' + 'JpZW5kX3Byb21vdGlvbnNCEQoPX21lc3NhZ2VfdXBkYXRlQggKBl9tZWRpYUIPCg1fbWVkaWFf' + 'dXBkYXRlQhEKD19jb250YWN0X3VwZGF0ZUISChBfY29udGFjdF9yZXF1ZXN0Qg0KC19mbGFtZV' + '9zeW5jQgwKCl9wdXNoX2tleXNCCwoJX3JlYWN0aW9uQg8KDV90ZXh0X21lc3NhZ2VCDwoNX2dy' + 'b3VwX2NyZWF0ZUINCgtfZ3JvdXBfam9pbkIPCg1fZ3JvdXBfdXBkYXRlQhoKGF9yZXNlbmRfZ3' + 'JvdXBfcHVibGljX2tleUIRCg9fZXJyb3JfbWVzc2FnZXNCGgoYX2FkZGl0aW9uYWxfZGF0YV9t' + 'ZXNzYWdlQhMKEV90eXBpbmdfaW5kaWNhdG9yQhkKF191c2VyX2Rpc2NvdmVyeV9yZXF1ZXN0Qh' + 'gKFl91c2VyX2Rpc2NvdmVyeV91cGRhdGVCGQoXX2tleV92ZXJpZmljYXRpb25fcHJvb2ZCGAoW' + 'X3Bhc3N3b3JkbGVzc19yZWNvdmVyeUIiCiBfcGFzc3dvcmRsZXNzX3JlY292ZXJ5X2hlYXJ0Ym' + 'VhdA=='); diff --git a/lib/src/model/protobuf/client/generated/passwordless_recovery.pb.dart b/lib/src/model/protobuf/client/generated/passwordless_recovery.pb.dart new file mode 100644 index 00000000..0481a587 --- /dev/null +++ b/lib/src/model/protobuf/client/generated/passwordless_recovery.pb.dart @@ -0,0 +1,559 @@ +// This is a generated file - do not edit. +// +// Generated from passwordless_recovery.proto. + +// @dart = 3.3 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names +// ignore_for_file: curly_braces_in_flow_control_structures +// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_relative_imports + +import 'dart:core' as $core; + +import 'package:fixnum/fixnum.dart' as $fixnum; +import 'package:protobuf/protobuf.dart' as $pb; + +export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions; + +/// Send from the person who tries to recover their account. +/// This can be done via a link, which will then be opend in the app of the contact. +/// The contact than has to manualy select from which user he got the request. +/// -> Using this phishing is harder, as the user has to manualy select the user to recovery +/// -> The user who wants to recover his account does not need to remember her old username +class RecoveryRequest extends $pb.GeneratedMessage { + factory RecoveryRequest({ + $fixnum.Int64? tempId, + $core.List<$core.int>? publicKey, + }) { + final result = create(); + if (tempId != null) result.tempId = tempId; + if (publicKey != null) result.publicKey = publicKey; + return result; + } + + RecoveryRequest._(); + + factory RecoveryRequest.fromBuffer($core.List<$core.int> data, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(data, registry); + factory RecoveryRequest.fromJson($core.String json, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(json, registry); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'RecoveryRequest', + package: const $pb.PackageName( + _omitMessageNames ? '' : 'passwordless_recovery'), + createEmptyInstance: create) + ..aInt64(1, _omitFieldNames ? '' : 'tempId') + ..a<$core.List<$core.int>>( + 2, _omitFieldNames ? '' : 'publicKey', $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + RecoveryRequest clone() => deepCopy(); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + RecoveryRequest copyWith(void Function(RecoveryRequest) updates) => + super.copyWith((message) => updates(message as RecoveryRequest)) + as RecoveryRequest; + + @$core.override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static RecoveryRequest create() => RecoveryRequest._(); + @$core.override + RecoveryRequest createEmptyInstance() => create(); + @$core.pragma('dart2js:noInline') + static RecoveryRequest getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static RecoveryRequest? _defaultInstance; + + @$pb.TagNumber(1) + $fixnum.Int64 get tempId => $_getI64(0); + @$pb.TagNumber(1) + set tempId($fixnum.Int64 value) => $_setInt64(0, value); + @$pb.TagNumber(1) + $core.bool hasTempId() => $_has(0); + @$pb.TagNumber(1) + void clearTempId() => $_clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get publicKey => $_getN(1); + @$pb.TagNumber(2) + set publicKey($core.List<$core.int> value) => $_setBytes(1, value); + @$pb.TagNumber(2) + $core.bool hasPublicKey() => $_has(1); + @$pb.TagNumber(2) + void clearPublicKey() => $_clearField(2); +} + +/// Used as envelope for TrustedFriendShare and RecoveryData +class EncryptedEnvelope extends $pb.GeneratedMessage { + factory EncryptedEnvelope({ + $core.List<$core.int>? encryptedData, + $core.List<$core.int>? iv, + $core.List<$core.int>? mac, + }) { + final result = create(); + if (encryptedData != null) result.encryptedData = encryptedData; + if (iv != null) result.iv = iv; + if (mac != null) result.mac = mac; + return result; + } + + EncryptedEnvelope._(); + + factory EncryptedEnvelope.fromBuffer($core.List<$core.int> data, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(data, registry); + factory EncryptedEnvelope.fromJson($core.String json, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(json, registry); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'EncryptedEnvelope', + package: const $pb.PackageName( + _omitMessageNames ? '' : 'passwordless_recovery'), + createEmptyInstance: create) + ..a<$core.List<$core.int>>( + 1, _omitFieldNames ? '' : 'encryptedData', $pb.PbFieldType.OY) + ..a<$core.List<$core.int>>( + 2, _omitFieldNames ? '' : 'iv', $pb.PbFieldType.OY) + ..a<$core.List<$core.int>>( + 3, _omitFieldNames ? '' : 'mac', $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + EncryptedEnvelope clone() => deepCopy(); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + EncryptedEnvelope copyWith(void Function(EncryptedEnvelope) updates) => + super.copyWith((message) => updates(message as EncryptedEnvelope)) + as EncryptedEnvelope; + + @$core.override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static EncryptedEnvelope create() => EncryptedEnvelope._(); + @$core.override + EncryptedEnvelope createEmptyInstance() => create(); + @$core.pragma('dart2js:noInline') + static EncryptedEnvelope getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static EncryptedEnvelope? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get encryptedData => $_getN(0); + @$pb.TagNumber(1) + set encryptedData($core.List<$core.int> value) => $_setBytes(0, value); + @$pb.TagNumber(1) + $core.bool hasEncryptedData() => $_has(0); + @$pb.TagNumber(1) + void clearEncryptedData() => $_clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get iv => $_getN(1); + @$pb.TagNumber(2) + set iv($core.List<$core.int> value) => $_setBytes(1, value); + @$pb.TagNumber(2) + $core.bool hasIv() => $_has(1); + @$pb.TagNumber(2) + void clearIv() => $_clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get mac => $_getN(2); + @$pb.TagNumber(3) + set mac($core.List<$core.int> value) => $_setBytes(2, value); + @$pb.TagNumber(3) + $core.bool hasMac() => $_has(2); + @$pb.TagNumber(3) + void clearMac() => $_clearField(3); +} + +class TrustedFriendShare_User extends $pb.GeneratedMessage { + factory TrustedFriendShare_User({ + $fixnum.Int64? userId, + $core.String? displayName, + $core.List<$core.int>? avatar, + }) { + final result = create(); + if (userId != null) result.userId = userId; + if (displayName != null) result.displayName = displayName; + if (avatar != null) result.avatar = avatar; + return result; + } + + TrustedFriendShare_User._(); + + factory TrustedFriendShare_User.fromBuffer($core.List<$core.int> data, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(data, registry); + factory TrustedFriendShare_User.fromJson($core.String json, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(json, registry); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'TrustedFriendShare.User', + package: const $pb.PackageName( + _omitMessageNames ? '' : 'passwordless_recovery'), + createEmptyInstance: create) + ..aInt64(1, _omitFieldNames ? '' : 'userId') + ..aOS(2, _omitFieldNames ? '' : 'displayName') + ..a<$core.List<$core.int>>( + 3, _omitFieldNames ? '' : 'avatar', $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + TrustedFriendShare_User clone() => deepCopy(); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + TrustedFriendShare_User copyWith( + void Function(TrustedFriendShare_User) updates) => + super.copyWith((message) => updates(message as TrustedFriendShare_User)) + as TrustedFriendShare_User; + + @$core.override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static TrustedFriendShare_User create() => TrustedFriendShare_User._(); + @$core.override + TrustedFriendShare_User createEmptyInstance() => create(); + @$core.pragma('dart2js:noInline') + static TrustedFriendShare_User getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static TrustedFriendShare_User? _defaultInstance; + + @$pb.TagNumber(1) + $fixnum.Int64 get userId => $_getI64(0); + @$pb.TagNumber(1) + set userId($fixnum.Int64 value) => $_setInt64(0, value); + @$pb.TagNumber(1) + $core.bool hasUserId() => $_has(0); + @$pb.TagNumber(1) + void clearUserId() => $_clearField(1); + + @$pb.TagNumber(2) + $core.String get displayName => $_getSZ(1); + @$pb.TagNumber(2) + set displayName($core.String value) => $_setString(1, value); + @$pb.TagNumber(2) + $core.bool hasDisplayName() => $_has(1); + @$pb.TagNumber(2) + void clearDisplayName() => $_clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get avatar => $_getN(2); + @$pb.TagNumber(3) + set avatar($core.List<$core.int> value) => $_setBytes(2, value); + @$pb.TagNumber(3) + $core.bool hasAvatar() => $_has(2); + @$pb.TagNumber(3) + void clearAvatar() => $_clearField(3); +} + +/// Send from the trusted friend to +/// This is encrypted with the received public key. +class TrustedFriendShare extends $pb.GeneratedMessage { + factory TrustedFriendShare({ + TrustedFriendShare_User? trustedFriend, + TrustedFriendShare_User? shareUser, + $core.int? threshold, + $core.List<$core.int>? sharedSecretData, + }) { + final result = create(); + if (trustedFriend != null) result.trustedFriend = trustedFriend; + if (shareUser != null) result.shareUser = shareUser; + if (threshold != null) result.threshold = threshold; + if (sharedSecretData != null) result.sharedSecretData = sharedSecretData; + return result; + } + + TrustedFriendShare._(); + + factory TrustedFriendShare.fromBuffer($core.List<$core.int> data, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(data, registry); + factory TrustedFriendShare.fromJson($core.String json, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(json, registry); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'TrustedFriendShare', + package: const $pb.PackageName( + _omitMessageNames ? '' : 'passwordless_recovery'), + createEmptyInstance: create) + ..aOM(1, _omitFieldNames ? '' : 'trustedFriend', + subBuilder: TrustedFriendShare_User.create) + ..aOM(2, _omitFieldNames ? '' : 'shareUser', + subBuilder: TrustedFriendShare_User.create) + ..aI(3, _omitFieldNames ? '' : 'threshold') + ..a<$core.List<$core.int>>( + 4, _omitFieldNames ? '' : 'sharedSecretData', $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + TrustedFriendShare clone() => deepCopy(); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + TrustedFriendShare copyWith(void Function(TrustedFriendShare) updates) => + super.copyWith((message) => updates(message as TrustedFriendShare)) + as TrustedFriendShare; + + @$core.override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static TrustedFriendShare create() => TrustedFriendShare._(); + @$core.override + TrustedFriendShare createEmptyInstance() => create(); + @$core.pragma('dart2js:noInline') + static TrustedFriendShare getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static TrustedFriendShare? _defaultInstance; + + /// This allows to display the user which user has send him his recovery data. + @$pb.TagNumber(1) + TrustedFriendShare_User get trustedFriend => $_getN(0); + @$pb.TagNumber(1) + set trustedFriend(TrustedFriendShare_User value) => $_setField(1, value); + @$pb.TagNumber(1) + $core.bool hasTrustedFriend() => $_has(0); + @$pb.TagNumber(1) + void clearTrustedFriend() => $_clearField(1); + @$pb.TagNumber(1) + TrustedFriendShare_User ensureTrustedFriend() => $_ensure(0); + + /// This allows to display the userdata, showing that he is recovering the correct person. + @$pb.TagNumber(2) + TrustedFriendShare_User get shareUser => $_getN(1); + @$pb.TagNumber(2) + set shareUser(TrustedFriendShare_User value) => $_setField(2, value); + @$pb.TagNumber(2) + $core.bool hasShareUser() => $_has(1); + @$pb.TagNumber(2) + void clearShareUser() => $_clearField(2); + @$pb.TagNumber(2) + TrustedFriendShare_User ensureShareUser() => $_ensure(1); + + /// The minimum threshold required to decrypte the shares. + @$pb.TagNumber(3) + $core.int get threshold => $_getIZ(2); + @$pb.TagNumber(3) + set threshold($core.int value) => $_setSignedInt32(2, value); + @$pb.TagNumber(3) + $core.bool hasThreshold() => $_has(2); + @$pb.TagNumber(3) + void clearThreshold() => $_clearField(3); + + /// The actual share which will become: SharedSecretData + @$pb.TagNumber(4) + $core.List<$core.int> get sharedSecretData => $_getN(3); + @$pb.TagNumber(4) + set sharedSecretData($core.List<$core.int> value) => $_setBytes(3, value); + @$pb.TagNumber(4) + $core.bool hasSharedSecretData() => $_has(3); + @$pb.TagNumber(4) + void clearSharedSecretData() => $_clearField(4); +} + +/// The user identity keys. Can be used to restore the data backup. +class RecoveryData extends $pb.GeneratedMessage { + factory RecoveryData({ + $fixnum.Int64? userId, + $core.List<$core.int>? keyManager, + }) { + final result = create(); + if (userId != null) result.userId = userId; + if (keyManager != null) result.keyManager = keyManager; + return result; + } + + RecoveryData._(); + + factory RecoveryData.fromBuffer($core.List<$core.int> data, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(data, registry); + factory RecoveryData.fromJson($core.String json, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(json, registry); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'RecoveryData', + package: const $pb.PackageName( + _omitMessageNames ? '' : 'passwordless_recovery'), + createEmptyInstance: create) + ..aInt64(1, _omitFieldNames ? '' : 'userId') + ..a<$core.List<$core.int>>( + 3, _omitFieldNames ? '' : 'keyManager', $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + RecoveryData clone() => deepCopy(); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + RecoveryData copyWith(void Function(RecoveryData) updates) => + super.copyWith((message) => updates(message as RecoveryData)) + as RecoveryData; + + @$core.override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static RecoveryData create() => RecoveryData._(); + @$core.override + RecoveryData createEmptyInstance() => create(); + @$core.pragma('dart2js:noInline') + static RecoveryData getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static RecoveryData? _defaultInstance; + + @$pb.TagNumber(1) + $fixnum.Int64 get userId => $_getI64(0); + @$pb.TagNumber(1) + set userId($fixnum.Int64 value) => $_setInt64(0, value); + @$pb.TagNumber(1) + $core.bool hasUserId() => $_has(0); + @$pb.TagNumber(1) + void clearUserId() => $_clearField(1); + + @$pb.TagNumber(3) + $core.List<$core.int> get keyManager => $_getN(1); + @$pb.TagNumber(3) + set keyManager($core.List<$core.int> value) => $_setBytes(1, value); + @$pb.TagNumber(3) + $core.bool hasKeyManager() => $_has(1); + @$pb.TagNumber(3) + void clearKeyManager() => $_clearField(3); +} + +/// After received all shares this is decrypted by the user restoring its own +class SharedSecretData extends $pb.GeneratedMessage { + factory SharedSecretData({ + $core.List<$core.int>? recoveryData, + $core.List<$core.int>? pinSeed, + $core.List<$core.int>? pinUnlockToken, + $core.String? emailHint, + $core.List<$core.int>? encryptedServerKeyNonce, + $core.List<$core.int>? encryptedServerKeyMac, + }) { + final result = create(); + if (recoveryData != null) result.recoveryData = recoveryData; + if (pinSeed != null) result.pinSeed = pinSeed; + if (pinUnlockToken != null) result.pinUnlockToken = pinUnlockToken; + if (emailHint != null) result.emailHint = emailHint; + if (encryptedServerKeyNonce != null) + result.encryptedServerKeyNonce = encryptedServerKeyNonce; + if (encryptedServerKeyMac != null) + result.encryptedServerKeyMac = encryptedServerKeyMac; + return result; + } + + SharedSecretData._(); + + factory SharedSecretData.fromBuffer($core.List<$core.int> data, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(data, registry); + factory SharedSecretData.fromJson($core.String json, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(json, registry); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'SharedSecretData', + package: const $pb.PackageName( + _omitMessageNames ? '' : 'passwordless_recovery'), + createEmptyInstance: create) + ..a<$core.List<$core.int>>( + 1, _omitFieldNames ? '' : 'recoveryData', $pb.PbFieldType.OY) + ..a<$core.List<$core.int>>( + 2, _omitFieldNames ? '' : 'pinSeed', $pb.PbFieldType.OY) + ..a<$core.List<$core.int>>( + 3, _omitFieldNames ? '' : 'pinUnlockToken', $pb.PbFieldType.OY) + ..aOS(4, _omitFieldNames ? '' : 'emailHint') + ..a<$core.List<$core.int>>( + 5, _omitFieldNames ? '' : 'encryptedServerKeyNonce', $pb.PbFieldType.OY) + ..a<$core.List<$core.int>>( + 6, _omitFieldNames ? '' : 'encryptedServerKeyMac', $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + SharedSecretData clone() => deepCopy(); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + SharedSecretData copyWith(void Function(SharedSecretData) updates) => + super.copyWith((message) => updates(message as SharedSecretData)) + as SharedSecretData; + + @$core.override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SharedSecretData create() => SharedSecretData._(); + @$core.override + SharedSecretData createEmptyInstance() => create(); + @$core.pragma('dart2js:noInline') + static SharedSecretData getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SharedSecretData? _defaultInstance; + + /// The recovery data is encrypted in case a second factor was chosen. + @$pb.TagNumber(1) + $core.List<$core.int> get recoveryData => $_getN(0); + @$pb.TagNumber(1) + set recoveryData($core.List<$core.int> value) => $_setBytes(0, value); + @$pb.TagNumber(1) + $core.bool hasRecoveryData() => $_has(0); + @$pb.TagNumber(1) + void clearRecoveryData() => $_clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get pinSeed => $_getN(1); + @$pb.TagNumber(2) + set pinSeed($core.List<$core.int> value) => $_setBytes(1, value); + @$pb.TagNumber(2) + $core.bool hasPinSeed() => $_has(1); + @$pb.TagNumber(2) + void clearPinSeed() => $_clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get pinUnlockToken => $_getN(2); + @$pb.TagNumber(3) + set pinUnlockToken($core.List<$core.int> value) => $_setBytes(2, value); + @$pb.TagNumber(3) + $core.bool hasPinUnlockToken() => $_has(2); + @$pb.TagNumber(3) + void clearPinUnlockToken() => $_clearField(3); + + @$pb.TagNumber(4) + $core.String get emailHint => $_getSZ(3); + @$pb.TagNumber(4) + set emailHint($core.String value) => $_setString(3, value); + @$pb.TagNumber(4) + $core.bool hasEmailHint() => $_has(3); + @$pb.TagNumber(4) + void clearEmailHint() => $_clearField(4); + + @$pb.TagNumber(5) + $core.List<$core.int> get encryptedServerKeyNonce => $_getN(4); + @$pb.TagNumber(5) + set encryptedServerKeyNonce($core.List<$core.int> value) => + $_setBytes(4, value); + @$pb.TagNumber(5) + $core.bool hasEncryptedServerKeyNonce() => $_has(4); + @$pb.TagNumber(5) + void clearEncryptedServerKeyNonce() => $_clearField(5); + + @$pb.TagNumber(6) + $core.List<$core.int> get encryptedServerKeyMac => $_getN(5); + @$pb.TagNumber(6) + set encryptedServerKeyMac($core.List<$core.int> value) => + $_setBytes(5, value); + @$pb.TagNumber(6) + $core.bool hasEncryptedServerKeyMac() => $_has(5); + @$pb.TagNumber(6) + void clearEncryptedServerKeyMac() => $_clearField(6); +} + +const $core.bool _omitFieldNames = + $core.bool.fromEnvironment('protobuf.omit_field_names'); +const $core.bool _omitMessageNames = + $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/lib/src/model/protobuf/client/generated/passwordless_recovery.pbenum.dart b/lib/src/model/protobuf/client/generated/passwordless_recovery.pbenum.dart new file mode 100644 index 00000000..ac5dfc09 --- /dev/null +++ b/lib/src/model/protobuf/client/generated/passwordless_recovery.pbenum.dart @@ -0,0 +1,11 @@ +// This is a generated file - do not edit. +// +// Generated from passwordless_recovery.proto. + +// @dart = 3.3 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names +// ignore_for_file: curly_braces_in_flow_control_structures +// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_relative_imports diff --git a/lib/src/model/protobuf/client/generated/passwordless_recovery.pbjson.dart b/lib/src/model/protobuf/client/generated/passwordless_recovery.pbjson.dart new file mode 100644 index 00000000..cc87f864 --- /dev/null +++ b/lib/src/model/protobuf/client/generated/passwordless_recovery.pbjson.dart @@ -0,0 +1,182 @@ +// This is a generated file - do not edit. +// +// Generated from passwordless_recovery.proto. + +// @dart = 3.3 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names +// ignore_for_file: curly_braces_in_flow_control_structures +// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_relative_imports +// ignore_for_file: unused_import + +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use recoveryRequestDescriptor instead') +const RecoveryRequest$json = { + '1': 'RecoveryRequest', + '2': [ + {'1': 'temp_id', '3': 1, '4': 1, '5': 3, '10': 'tempId'}, + {'1': 'public_key', '3': 2, '4': 1, '5': 12, '10': 'publicKey'}, + ], +}; + +/// Descriptor for `RecoveryRequest`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List recoveryRequestDescriptor = $convert.base64Decode( + 'Cg9SZWNvdmVyeVJlcXVlc3QSFwoHdGVtcF9pZBgBIAEoA1IGdGVtcElkEh0KCnB1YmxpY19rZX' + 'kYAiABKAxSCXB1YmxpY0tleQ=='); + +@$core.Deprecated('Use encryptedEnvelopeDescriptor instead') +const EncryptedEnvelope$json = { + '1': 'EncryptedEnvelope', + '2': [ + {'1': 'encrypted_data', '3': 1, '4': 1, '5': 12, '10': 'encryptedData'}, + {'1': 'iv', '3': 2, '4': 1, '5': 12, '10': 'iv'}, + {'1': 'mac', '3': 3, '4': 1, '5': 12, '10': 'mac'}, + ], +}; + +/// Descriptor for `EncryptedEnvelope`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List encryptedEnvelopeDescriptor = $convert.base64Decode( + 'ChFFbmNyeXB0ZWRFbnZlbG9wZRIlCg5lbmNyeXB0ZWRfZGF0YRgBIAEoDFINZW5jcnlwdGVkRG' + 'F0YRIOCgJpdhgCIAEoDFICaXYSEAoDbWFjGAMgASgMUgNtYWM='); + +@$core.Deprecated('Use trustedFriendShareDescriptor instead') +const TrustedFriendShare$json = { + '1': 'TrustedFriendShare', + '2': [ + { + '1': 'trusted_friend', + '3': 1, + '4': 1, + '5': 11, + '6': '.passwordless_recovery.TrustedFriendShare.User', + '10': 'trustedFriend' + }, + { + '1': 'share_user', + '3': 2, + '4': 1, + '5': 11, + '6': '.passwordless_recovery.TrustedFriendShare.User', + '10': 'shareUser' + }, + {'1': 'threshold', '3': 3, '4': 1, '5': 5, '10': 'threshold'}, + { + '1': 'shared_secret_data', + '3': 4, + '4': 1, + '5': 12, + '10': 'sharedSecretData' + }, + ], + '3': [TrustedFriendShare_User$json], +}; + +@$core.Deprecated('Use trustedFriendShareDescriptor instead') +const TrustedFriendShare_User$json = { + '1': 'User', + '2': [ + {'1': 'user_id', '3': 1, '4': 1, '5': 3, '10': 'userId'}, + {'1': 'display_name', '3': 2, '4': 1, '5': 9, '10': 'displayName'}, + {'1': 'avatar', '3': 3, '4': 1, '5': 12, '10': 'avatar'}, + ], +}; + +/// Descriptor for `TrustedFriendShare`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List trustedFriendShareDescriptor = $convert.base64Decode( + 'ChJUcnVzdGVkRnJpZW5kU2hhcmUSVQoOdHJ1c3RlZF9mcmllbmQYASABKAsyLi5wYXNzd29yZG' + 'xlc3NfcmVjb3ZlcnkuVHJ1c3RlZEZyaWVuZFNoYXJlLlVzZXJSDXRydXN0ZWRGcmllbmQSTQoK' + 'c2hhcmVfdXNlchgCIAEoCzIuLnBhc3N3b3JkbGVzc19yZWNvdmVyeS5UcnVzdGVkRnJpZW5kU2' + 'hhcmUuVXNlclIJc2hhcmVVc2VyEhwKCXRocmVzaG9sZBgDIAEoBVIJdGhyZXNob2xkEiwKEnNo' + 'YXJlZF9zZWNyZXRfZGF0YRgEIAEoDFIQc2hhcmVkU2VjcmV0RGF0YRpaCgRVc2VyEhcKB3VzZX' + 'JfaWQYASABKANSBnVzZXJJZBIhCgxkaXNwbGF5X25hbWUYAiABKAlSC2Rpc3BsYXlOYW1lEhYK' + 'BmF2YXRhchgDIAEoDFIGYXZhdGFy'); + +@$core.Deprecated('Use recoveryDataDescriptor instead') +const RecoveryData$json = { + '1': 'RecoveryData', + '2': [ + {'1': 'user_id', '3': 1, '4': 1, '5': 3, '10': 'userId'}, + {'1': 'key_manager', '3': 3, '4': 1, '5': 12, '10': 'keyManager'}, + ], +}; + +/// Descriptor for `RecoveryData`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List recoveryDataDescriptor = $convert.base64Decode( + 'CgxSZWNvdmVyeURhdGESFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkEh8KC2tleV9tYW5hZ2VyGA' + 'MgASgMUgprZXlNYW5hZ2Vy'); + +@$core.Deprecated('Use sharedSecretDataDescriptor instead') +const SharedSecretData$json = { + '1': 'SharedSecretData', + '2': [ + {'1': 'recovery_data', '3': 1, '4': 1, '5': 12, '10': 'recoveryData'}, + { + '1': 'pin_seed', + '3': 2, + '4': 1, + '5': 12, + '9': 0, + '10': 'pinSeed', + '17': true + }, + { + '1': 'pin_unlock_token', + '3': 3, + '4': 1, + '5': 12, + '9': 1, + '10': 'pinUnlockToken', + '17': true + }, + { + '1': 'email_hint', + '3': 4, + '4': 1, + '5': 9, + '9': 2, + '10': 'emailHint', + '17': true + }, + { + '1': 'encrypted_server_key_nonce', + '3': 5, + '4': 1, + '5': 12, + '9': 3, + '10': 'encryptedServerKeyNonce', + '17': true + }, + { + '1': 'encrypted_server_key_mac', + '3': 6, + '4': 1, + '5': 12, + '9': 4, + '10': 'encryptedServerKeyMac', + '17': true + }, + ], + '8': [ + {'1': '_pin_seed'}, + {'1': '_pin_unlock_token'}, + {'1': '_email_hint'}, + {'1': '_encrypted_server_key_nonce'}, + {'1': '_encrypted_server_key_mac'}, + ], +}; + +/// Descriptor for `SharedSecretData`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List sharedSecretDataDescriptor = $convert.base64Decode( + 'ChBTaGFyZWRTZWNyZXREYXRhEiMKDXJlY292ZXJ5X2RhdGEYASABKAxSDHJlY292ZXJ5RGF0YR' + 'IeCghwaW5fc2VlZBgCIAEoDEgAUgdwaW5TZWVkiAEBEi0KEHBpbl91bmxvY2tfdG9rZW4YAyAB' + 'KAxIAVIOcGluVW5sb2NrVG9rZW6IAQESIgoKZW1haWxfaGludBgEIAEoCUgCUgllbWFpbEhpbn' + 'SIAQESQAoaZW5jcnlwdGVkX3NlcnZlcl9rZXlfbm9uY2UYBSABKAxIA1IXZW5jcnlwdGVkU2Vy' + 'dmVyS2V5Tm9uY2WIAQESPAoYZW5jcnlwdGVkX3NlcnZlcl9rZXlfbWFjGAYgASgMSARSFWVuY3' + 'J5cHRlZFNlcnZlcktleU1hY4gBAUILCglfcGluX3NlZWRCEwoRX3Bpbl91bmxvY2tfdG9rZW5C' + 'DQoLX2VtYWlsX2hpbnRCHQobX2VuY3J5cHRlZF9zZXJ2ZXJfa2V5X25vbmNlQhsKGV9lbmNyeX' + 'B0ZWRfc2VydmVyX2tleV9tYWM='); diff --git a/lib/src/model/protobuf/client/messages.proto b/lib/src/model/protobuf/client/messages.proto index e9ed3067..b3bd574c 100644 --- a/lib/src/model/protobuf/client/messages.proto +++ b/lib/src/model/protobuf/client/messages.proto @@ -58,6 +58,8 @@ message EncryptedContent { optional UserDiscoveryRequest user_discovery_request = 22; optional UserDiscoveryUpdate user_discovery_update = 23; optional KeyVerificationProof key_verification_proof = 24; + optional PasswordLessRecovery passwordless_recovery = 26; + optional PasswordLessRecoveryHeartbeat passwordless_recovery_heartbeat = 27; message ErrorMessages { enum Type { @@ -82,9 +84,7 @@ message EncryptedContent { bytes group_public_key = 1; } - message ResendGroupPublicKey { - - } + message ResendGroupPublicKey {} message GroupUpdate { string group_action_type = 1; // GroupActionType.name @@ -217,4 +217,13 @@ message EncryptedContent { bytes calculated_mac = 1; } + message PasswordLessRecovery { + optional bytes recoverySecretShare = 1; + bool delete = 2; + } + + message PasswordLessRecoveryHeartbeat { + bytes hash = 1; + } + } \ No newline at end of file diff --git a/rust/src/passwordless_recovery/types.proto b/lib/src/model/protobuf/client/passwordless_recovery.proto similarity index 58% rename from rust/src/passwordless_recovery/types.proto rename to lib/src/model/protobuf/client/passwordless_recovery.proto index ef911d77..2a7f1852 100644 --- a/rust/src/passwordless_recovery/types.proto +++ b/lib/src/model/protobuf/client/passwordless_recovery.proto @@ -46,40 +46,24 @@ message TrustedFriendShare { } } -// After received all shares this is decrypted by the user restoring its own -message SharedSecretData { - - // No second factor was selected - optional RecoveryData recovery_data = 1; - - - // Server has - optional SecondFactorMail second_factor_mail = 2; - optional SecondFactorPin second_factor_pin = 3; - - // The recovery data in case a second factor was used - // The decryption key is loaded from the server either using the PIN or the MAIL - optional bytes recovery_data_encrypted = 4; - - - message SecondFactorPin { - // Required to try the PIN to get the share from the server. - // This prevents that someone else can lock the pin, as the server only - // allows 3 tries then after 1 day again 3 tries until the key is deleted. - bytes unlock_token = 1; - // This never is send to the server but used to hash the pin before sending it to the server. - // This prevents that the server every knows the shot 4-diget PIN. - bytes pin_seed = 2; - } - - message SecondFactorMail {} - -} - -// The data which is recovered at the end. -// The backup_master_key allows to recover the actual backup uploaded in the background to the server. -// In case the backup is not available any more the user can use its user_id and his private_key to requister as a new user. +// The user identity keys. Can be used to restore the data backup. message RecoveryData { int64 user_id = 1; bytes key_manager = 3; } + +// After received all shares this is decrypted by the user restoring its own +message SharedSecretData { + + // The recovery data is encrypted in case a second factor was chosen. + bytes recovery_data = 1; + + optional bytes pin_seed = 2; + optional bytes pin_unlock_token = 3; + + optional string email_hint = 4; + optional bytes encrypted_server_key_nonce = 5; + optional bytes encrypted_server_key_mac = 6; + +} + diff --git a/lib/src/services/api.service.dart b/lib/src/services/api.service.dart index 09531df5..1aacbbed 100644 --- a/lib/src/services/api.service.dart +++ b/lib/src/services/api.service.dart @@ -758,6 +758,22 @@ class ApiService { return sendRequestSync(req, contactId: userId.toInt()); } + Future registerPasswordLessRecovery( + List encryptedServerKey, + List? pinUnlockToken, + ) async { + final req = createClientToServerFromApplicationData( + ApplicationData( + registerPasswordlessRecovery: + ApplicationData_RegisterPasswordLessRecovery( + encryptedServerKey: encryptedServerKey, + pinUnlockToken: pinUnlockToken, + ), + ), + ); + return sendRequestSync(req); + } + Future addAdditionalUser(Int64 userId) async { final get = ApplicationData_AddAdditionalUser()..userId = userId; final appData = ApplicationData()..addAdditionalUser = get; diff --git a/lib/src/services/api/server_messages.api.dart b/lib/src/services/api/server_messages.api.dart index 90b13f26..eb1276c1 100644 --- a/lib/src/services/api/server_messages.api.dart +++ b/lib/src/services/api/server_messages.api.dart @@ -33,6 +33,7 @@ import 'package:twonly/src/services/group.service.dart'; import 'package:twonly/src/services/key_verification.service.dart'; import 'package:twonly/src/services/notifications/background.notifications.dart'; import 'package:twonly/src/services/notifications/fcm.notifications.dart'; +import 'package:twonly/src/services/passwordless_recovery.service.dart'; import 'package:twonly/src/services/signal/encryption.signal.dart'; import 'package:twonly/src/services/signal/session.signal.dart'; import 'package:twonly/src/utils/log.dart'; @@ -370,6 +371,24 @@ Future<(EncryptedContent?, PlaintextContent?)> handleEncryptedMessage( return (null, null); } + if (content.hasPasswordlessRecovery()) { + await PasswordlessRecoveryService.handlePasswordlessRecovery( + fromUserId, + content.passwordlessRecovery, + receiptId, + ); + return (null, null); + } + + if (content.hasPasswordlessRecoveryHeartbeat()) { + await PasswordlessRecoveryService.handlePasswordlessRecoveryHeartbeat( + fromUserId, + content.passwordlessRecoveryHeartbeat, + receiptId, + ); + return (null, null); + } + if (content.hasContactUpdate()) { await handleContactUpdate( fromUserId, diff --git a/lib/src/services/passwordless_recovery.service.dart b/lib/src/services/passwordless_recovery.service.dart index 147a4c7c..22de867d 100644 --- a/lib/src/services/passwordless_recovery.service.dart +++ b/lib/src/services/passwordless_recovery.service.dart @@ -1,15 +1,25 @@ import 'dart:async'; -import 'dart:convert' show base64Encode, utf8; -import 'dart:typed_data'; +import 'dart:convert' show utf8; +import 'package:clock/clock.dart'; +import 'package:collection/collection.dart'; +import 'package:crypto/crypto.dart' hide Hmac; import 'package:cryptography_flutter_plus/cryptography_flutter_plus.dart' show FlutterChacha20; -import 'package:cryptography_plus/cryptography_plus.dart' show SecretKey; -import 'package:hashlib/hashlib.dart' show Scrypt; +import 'package:cryptography_plus/cryptography_plus.dart' show Hmac, SecretKey; +import 'package:drift/drift.dart'; +import 'package:fixnum/fixnum.dart'; +import 'package:twonly/core/bridge/wrapper.dart'; +import 'package:twonly/core/bridge/wrapper/key_manager.dart'; import 'package:twonly/locator.dart'; +import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/model/json/userdata.model.dart' show PasswordLessRecovery; -import 'package:twonly/src/model/protobuf/client/generated/passwordless_recovery/types.pb.dart'; +import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart' + as pb; +import 'package:twonly/src/model/protobuf/client/generated/passwordless_recovery.pb.dart'; +import 'package:twonly/src/services/api/messages.api.dart'; +import 'package:twonly/src/services/user.service.dart'; import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/misc.dart'; @@ -22,94 +32,352 @@ class PasswordlessRecoveryService { required String secondFactorValue, required int threshold, }) async { - await twonlyDB.contactsDao.resetRecoveryDataForAllContacts(); + // 1. Get all currently trusted friends contacts and send them delete messages + final oldTrustedFriends = await (twonlyDB.select( + twonlyDB.contacts, + )..where((t) => t.recoveryIsTrustedFriend.equals(true))).get(); - // 2. Update the user model configuration + for (final contact in oldTrustedFriends) { + try { + await sendCipherText( + contact.userId, + pb.EncryptedContent( + passwordlessRecovery: pb.EncryptedContent_PasswordLessRecovery( + delete: true, + ), + ), + ); + } catch (e) { + Log.error( + 'Failed to send delete PasswordLessRecovery message to contact ${contact.userId}: $e', + ); + } + } + + // 1. Reset current recovery data to ensure a clean state + + await twonlyDB.contactsDao.resetRecoveryDataForAllContacts(); + await UserService.update((u) => u.passwordLessRecovery = null); final config = PasswordLessRecovery(); + final chacha20 = FlutterChacha20.poly1305Aead(); - final serverKey = getRandomUint8List(32); - Uint8List? protectedEmailServerKey; - Uint8List? pinUnlockToken; - Uint8List? protectedPin; + // 2. If enabled, handle the second factor and create serverKey + + Uint8List? serverKey; + Uint8List? encryptedServerKey; + + SecretKey? secondFactorEncryptedServerKeyKey; + String? emailHint; switch (secondFactorType) { case SecondFactorType.email: - final emailSeed = getRandomUint8List(32); - - // Store it, so the user can see it again. - config.email = secondFactorValue; - - final chacha20 = FlutterChacha20.poly1305Aead(); - - final scrypt = Scrypt( - cost: 65536, - salt: emailSeed, - ); - - final protectedEmailKey = scrypt - .convert(utf8.encode(secondFactorValue)) - .bytes; - - // there must be a emailSeed like for the pin... // The serverKey is encrypted with the email; this protects the server from seeing the user's email address, while // also ensuring that the server can only send the real secret to the user's configured email, as a different // email will result in a different secret key. - final secretBox = await chacha20.encrypt( - serverKey, - secretKey: SecretKey( - Uint8List.fromList(protectedEmailKey), - ), - nonce: chacha20.newNonce(), - ); + // This is only stored so the user can see there email, and verify that he has set the valid mail... + config.email = secondFactorValue; + emailHint = createEmailHint(secondFactorValue); - protectedEmailServerKey = EncryptedEnvelope( - encryptedData: secretBox.cipherText, - // iv: secretBox.nonce, - mac: secretBox.mac.bytes, - ).writeToBuffer(); + // E-Mail Protection: + // - Server can only learn the email during recovery. Ensured as the server gets the NONCE and MAC to decrpyt during recovery. + // - Trusted-friends: Server key is send to the mail, they whould need access to the user's mail account. + secondFactorEncryptedServerKeyKey = SecretKey( + Uint8List.fromList(utf8.encode(config.email!)), + ); case SecondFactorType.pin: - final pinSeed = getRandomUint8List(32); - pinUnlockToken = getRandomUint8List(32); - // The pin seed is to ensure that the server does never learns the real 4-digit pin. The seed is never send to - // the server. As the pin are heavily protected against brute-forcing and will be discared by the server after X - // tries, this prevents that a malicous user trigger this deletion... - config.pinSeed = base64Encode(pinSeed); - config.pinUnlockToken = base64Encode(pinUnlockToken); + // The pin seed - never shared with the server - ensures that the server is unable to brute-force real user's pin. + config.pinSeed = getRandomUint8List(32); - final scrypt = Scrypt( - cost: 65536, - salt: pinSeed, + // As the pin is heavily protected against brute-forcing e.g. will be deleted by the server after X tries, the + // unlock token is required to prevent a malicous user (except the trusted friends) to triger this deletion. + config.pinUnlockToken = getRandomUint8List(32); + + // Brute-force protection for the user's pin: + // - Server: Does not know the seed. + // - Trusted friends: Can only check the result X times before the server deletes the key. + final pinProtectionKey = await Hmac.sha256().calculateMac( + Uint8List.fromList(utf8.encode(secondFactorValue)), + secretKey: SecretKey(config.pinSeed!), ); - final key = scrypt.convert(utf8.encode(secondFactorValue)).bytes; - protectedPin = key.sublist(0, 32); + // To restore the user has to provide the server with this encryption key. The server then can verify the + // correct pin was entered, when decrypting the server key as he also receives the mac and nonce from the user + // during recovery. Only when the mac is correct the server provides the user with the serverKey. + secondFactorEncryptedServerKeyKey = SecretKey(pinProtectionKey.bytes); case SecondFactorType.none: } - // 3. Use the second factor and generate the shares... + if (secondFactorEncryptedServerKeyKey != null) { + // The server key is used to encrypt the RecoveryData of the users. This ensures that when the trusted friends + // colaberate, they additional need the serverKey to decrypt the user's key. + serverKey = getRandomUint8List(32); - // Generate the shares, and store them in the contacrs.table. + final secretBox = await chacha20.encrypt( + serverKey, + secretKey: secondFactorEncryptedServerKeyKey, + nonce: chacha20.newNonce(), + ); - Log.info('Enabling passwordless recovery with:'); - Log.info(' - Trusted Friends: $trustedFriendIds'); - Log.info(' - Second Factor Type: $secondFactorType'); - Log.info(' - Second Factor Value: $secondFactorValue'); - Log.info(' - Threshold: $threshold'); + // This is send to the server and then deleted localy + encryptedServerKey = Uint8List.fromList(secretBox.cipherText); - // Use the serverKey to protect the recovery_data_encrypted + // Because the server does not know the nonce and the mac, he is unable to link a email to the user and also + // unable to brute-force the pin. + config + ..encryptedServerKeyNonce = secretBox.nonce + ..encryptedServerKey = encryptedServerKey + ..encryptedServerKeyMac = secretBox.mac.bytes; + } - // 4. Send the data to the server: + // 3. Using shamir's secret to generate the shares for the users. - // to th server - // protectedPin, pinUnlockToken, protectedEmailServerKey; + // 3.1. Create the SharedSecretData - // 5. send to the contacts / implement the heartbeat check, and notify the user in case the hearbeath shows that to few users are active... + var recoveryData = RecoveryData( + userId: Int64(userService.currentUser.userId), + keyManager: await RustKeyManager.serialize(), + ).writeToBuffer(); + if (serverKey != null) { + // Second factor was enabled, so encrypt the recoveryData using the serverKey. + + final secretBox = await chacha20.encrypt( + recoveryData, + secretKey: SecretKey(serverKey), + nonce: chacha20.newNonce(), + ); + + recoveryData = EncryptedEnvelope( + encryptedData: secretBox.cipherText, + iv: secretBox.nonce, + mac: secretBox.mac.bytes, + ).writeToBuffer(); + } + + final sharedSecretData = SharedSecretData( + recoveryData: recoveryData, + pinSeed: config.pinSeed, + pinUnlockToken: config.pinUnlockToken, + emailHint: emailHint, + encryptedServerKeyMac: config.encryptedServerKeyMac, + encryptedServerKeyNonce: config.encryptedServerKeyNonce, + ).writeToBuffer(); + + // 3.2. Use the amount of trusted friends to generate the shares + + final List shares; + try { + shares = await RustUtils.generateShares( + secret: sharedSecretData, + total: trustedFriendIds.length, + threshold: threshold, + ); + + if (shares.length != trustedFriendIds.length) { + Log.error('shares.length != trustedFriendIds.length'); + return false; + } + } catch (e) { + Log.error('Failed to generate secret shares: $e'); + return false; + } + + // 3.4. Store the shares in the contact's rows + for (final contactId in trustedFriendIds) { + await twonlyDB.contactsDao.updateContact( + contactId, + ContactsCompanion( + recoveryIsTrustedFriend: const Value(true), + recoveryLastHeartbeat: const Value(null), + recoverySecretShare: Value(shares.removeLast()), + ), + ); + } + // The passwordless is configured sucessfully. return true; } + + static Future performHeartbeat() async { + final config = userService.currentUser.passwordLessRecovery; + + if (config != null) { + final lastHeartbeat = config.lastServerHeartbeat; + final isOlderThanAMonth = + lastHeartbeat != null && + clock.now().difference(lastHeartbeat).inDays > 30; + + if ((lastHeartbeat == null || isOlderThanAMonth) && + config.encryptedServerKey != null) { + final res = await apiService.registerPasswordLessRecovery( + config.encryptedServerKey!, + config.pinUnlockToken, + ); + + if (res.isSuccess) { + await UserService.update((u) { + u.passwordLessRecovery?.lastServerHeartbeat = clock.now(); + }); + } + } + + // Get all contacts where recoveryLastHeartbeat is NULL. Then for each contacts send + final pendingShares = + await (twonlyDB.select(twonlyDB.contacts)..where( + (t) => + t.recoveryIsTrustedFriend.equals(true) & + t.recoveryLastHeartbeat.isNull() & + t.recoverySecretShare.isNotNull(), + )) + .get(); + + for (final contact in pendingShares) { + try { + await sendCipherText( + contact.userId, + pb.EncryptedContent( + passwordlessRecovery: pb.EncryptedContent_PasswordLessRecovery( + recoverySecretShare: contact.recoverySecretShare, + delete: false, + ), + ), + ); + + await twonlyDB.contactsDao.updateContact( + contact.userId, + ContactsCompanion( + recoveryLastHeartbeat: Value(clock.now()), + ), + ); + } catch (e) { + Log.error( + 'Failed to send PasswordLessRecovery share to contact ${contact.userId}: $e', + ); + } + } + } + + // Send heartbeat to the friends I am a trusted friend. + final oneWeekAgo = clock.now().subtract(const Duration(days: 7)); + final trustedFriendsToNotify = + await (twonlyDB.select(twonlyDB.contacts)..where( + (t) => + t.recoveryContactsSecretShare.isNotNull() & + (t.recoveryContactsLastHeartbeat.isNull() | + t.recoveryContactsLastHeartbeat.isSmallerThanValue( + oneWeekAgo, + )), + )) + .get(); + + for (final contact in trustedFriendsToNotify) { + try { + final share = contact.recoveryContactsSecretShare!; + final hash = sha256.convert(share).bytes; + + await sendCipherText( + contact.userId, + pb.EncryptedContent( + passwordlessRecoveryHeartbeat: + pb.EncryptedContent_PasswordLessRecoveryHeartbeat( + hash: hash, + ), + ), + ); + + await twonlyDB.contactsDao.updateContact( + contact.userId, + ContactsCompanion( + recoveryContactsLastHeartbeat: Value(clock.now()), + ), + ); + } catch (e) { + Log.error( + 'Failed to send PasswordLessRecoveryHeartbeat to contact ${contact.userId}: $e', + ); + } + } + } + + static Future handlePasswordlessRecovery( + int fromUserId, + pb.EncryptedContent_PasswordLessRecovery msg, + String receiptId, + ) async { + if (msg.delete) { + Log.info( + '[$receiptId] Received request to delete passwordless recovery share from contact $fromUserId', + ); + await twonlyDB.contactsDao.updateContact( + fromUserId, + const ContactsCompanion( + recoveryContactsSecretShare: Value(null), + recoveryContactsLastHeartbeat: Value(null), + ), + ); + } else if (msg.hasRecoverySecretShare()) { + Log.info( + '[$receiptId] Received new passwordless recovery share from contact $fromUserId', + ); + await twonlyDB.contactsDao.updateContact( + fromUserId, + ContactsCompanion( + recoveryContactsSecretShare: Value( + Uint8List.fromList(msg.recoverySecretShare), + ), + recoveryContactsLastHeartbeat: const Value( + null, // this will trigger that a heartbeat will be send... + ), + ), + ); + } + } + + static Future handlePasswordlessRecoveryHeartbeat( + int fromUserId, + pb.EncryptedContent_PasswordLessRecoveryHeartbeat msg, + String receiptId, + ) async { + Log.info( + '[$receiptId] Received passwordless recovery heartbeat from contact $fromUserId', + ); + final contact = await twonlyDB.contactsDao.getContactById(fromUserId); + final storedShare = contact?.recoverySecretShare; + + if (storedShare == null) { + unawaited( + sendCipherText( + fromUserId, + pb.EncryptedContent( + passwordlessRecovery: pb.EncryptedContent_PasswordLessRecovery( + delete: true, + ), + ), + ), + ); + Log.warn( + '[$receiptId] Received passwordless recovery heartbeat from $fromUserId but we did not send him a secret share.', + ); + return; + } + + final computedHash = sha256.convert(storedShare).bytes; + final recoveryLastHeartbeat = + const ListEquality().equals(computedHash, msg.hash) + ? clock.now() + : null; // The stored share not valid (maybe a old backup was restored). This will cause the performHeartbeat to resend him his share + Log.info( + '[$receiptId] Got heartbeat: ($recoveryLastHeartbeat)', + ); + await twonlyDB.contactsDao.updateContact( + fromUserId, + ContactsCompanion( + recoveryLastHeartbeat: Value(recoveryLastHeartbeat), + ), + ); + } } diff --git a/lib/src/utils/misc.dart b/lib/src/utils/misc.dart index 0ddc1fbe..ed71ccde 100644 --- a/lib/src/utils/misc.dart +++ b/lib/src/utils/misc.dart @@ -405,3 +405,26 @@ String joinWithAnd(List items, String andWord) { if (items.length == 1) return items.first; return '${items.sublist(0, items.length - 1).join(', ')} $andWord ${items.last}'; } + +String createEmailHint(String email) { + final parts = email.split('@'); + if (parts.length != 2) return email; + + final local = parts[0]; + final domain = parts[1]; + + final localMasked = local.length > 2 + ? '${local[0]}${'*' * (local.length - 2)}${local[local.length - 1]}' + : local; + + final domainParts = domain.split('.'); + if (domainParts.isEmpty) return '$localMasked@$domain'; + + final domainName = domainParts[0]; + final domainNameMasked = domainName.length > 1 + ? '${domainName[0]}${'*' * (domainName.length - 1)}' + : domainName; + + final restDomain = domainParts.skip(1).join('.'); + return '$localMasked@$domainNameMasked${restDomain.isNotEmpty ? '.$restDomain' : ''}'; +} diff --git a/rust/build.rs b/rust/build.rs index 58d91327..135361e9 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -1,6 +1,5 @@ use std::io::Result; fn main() -> Result<()> { prost_build::compile_protos(&["src/user_discovery/types.proto"], &["src/"])?; - prost_build::compile_protos(&["src/passwordless_recovery/types.proto"], &["src/"])?; Ok(()) } diff --git a/rust/src/bridge/wrapper/key_manager.rs b/rust/src/bridge/wrapper/key_manager.rs index d7ba4b14..2bc1ad93 100644 --- a/rust/src/bridge/wrapper/key_manager.rs +++ b/rust/src/bridge/wrapper/key_manager.rs @@ -108,4 +108,12 @@ impl RustKeyManager { crate::keys::KeyManager::remove_from_keychain(&ctx.secure_storage)?; Ok(()) } + + /// Serialize the key_manager. Needed for the passwordless_recovery feature. + pub async fn serialize() -> Result> { + let ctx = get_twonly_flutter()?; + let key_manager = ctx.key_manager.lock().await; + let serialized_bytes = postcard::to_allocvec(&*key_manager)?; + Ok(serialized_bytes) + } } diff --git a/rust/src/bridge/wrapper/mod.rs b/rust/src/bridge/wrapper/mod.rs index 75173c53..756bf38c 100644 --- a/rust/src/bridge/wrapper/mod.rs +++ b/rust/src/bridge/wrapper/mod.rs @@ -1,3 +1,29 @@ pub mod backup; pub mod key_manager; pub mod user_discovery; + +use crate::error::Result; +use blahaj::{Share, Sharks}; + +pub struct RustUtils {} + +impl RustUtils { + pub fn generate_shares(secret: Vec, total: u8, threshold: u8) -> Result>> { + let sharks = Sharks(threshold); + let dealer = sharks.dealer(&secret); + let shares = dealer.take(total as usize).map(|x| Vec::from(&x)).collect(); + Ok(shares) + } + + pub fn recover_secret(shares: Vec>, threshold: u8) -> Result> { + let sharks = Sharks(threshold); + let shares: Vec = shares + .iter() + .filter_map(|x| Share::try_from(x.as_slice()).ok()) + .collect(); + let secret = sharks + .recover(&shares) + .map_err(|e| crate::error::TwonlyError::Generic(e.to_string()))?; + Ok(secret) + } +} diff --git a/rust/src/frb_generated.rs b/rust/src/frb_generated.rs index c63d3a4b..1b437d7e 100644 --- a/rust/src/frb_generated.rs +++ b/rust/src/frb_generated.rs @@ -26,6 +26,8 @@ // Section: imports +use crate::user_discovery::traits::UserDiscoveryStore; +use crate::user_discovery::traits::UserDiscoveryUtils; use flutter_rust_bridge::for_generated::byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt}; use flutter_rust_bridge::for_generated::{transform_result_dco, Lifetimeable, Lockable}; use flutter_rust_bridge::{Handler, IntoIntoDart}; @@ -38,7 +40,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 = -1867463121; +pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -508562557; // Section: executor @@ -544,6 +546,43 @@ fn wire__crate__bridge__wrapper__key_manager__rust_key_manager_remove_signed_pre })().await) } }) } +fn wire__crate__bridge__wrapper__key_manager__rust_key_manager_serialize_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_async::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "rust_key_manager_serialize", + 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| async move { + transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>( + (move || async move { + let output_ok = + crate::bridge::wrapper::key_manager::RustKeyManager::serialize() + .await?; + Ok(output_ok) + })() + .await, + ) + } + }, + ) +} fn wire__crate__bridge__wrapper__key_manager__rust_key_manager_set_user_id_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, @@ -600,6 +639,349 @@ let api_record = >::sse_decode(&mut deserializer);deserializer.end(); mo })().await) } }) } +fn wire__crate__bridge__wrapper__rust_utils_generate_shares_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: "rust_utils_generate_shares", + 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); + let api_secret = >::sse_decode(&mut deserializer); + let api_total = ::sse_decode(&mut deserializer); + let api_threshold = ::sse_decode(&mut deserializer); + deserializer.end(); + move |context| { + transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>( + (move || { + let output_ok = crate::bridge::wrapper::RustUtils::generate_shares( + api_secret, + api_total, + api_threshold, + )?; + Ok(output_ok) + })(), + ) + } + }, + ) +} +fn wire__crate__bridge__wrapper__rust_utils_recover_secret_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: "rust_utils_recover_secret", + 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); + let api_shares = >>::sse_decode(&mut deserializer); + let api_threshold = ::sse_decode(&mut deserializer); + deserializer.end(); + move |context| { + transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>( + (move || { + let output_ok = crate::bridge::wrapper::RustUtils::recover_secret( + api_shares, + api_threshold, + )?; + Ok(output_ok) + })(), + ) + } + }, + ) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_announced_user_by_public_id_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_get_announced_user_by_public_id", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_public_id = ::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::get_announced_user_by_public_id(&api_that, api_public_id).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_config_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_get_config", 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); + let api_that = ::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::get_config(&api_that).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_contact_promotion_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_get_contact_promotion", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_contact_id = ::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::get_contact_promotion(&api_that, api_contact_id).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_contact_version_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_get_contact_version", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_contact_id = ::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::get_contact_version(&api_that, api_contact_id).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_other_promotions_by_public_id_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_get_other_promotions_by_public_id", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_public_id = ::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::get_other_promotions_by_public_id(&api_that, api_public_id).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_own_promotions_after_version_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_get_own_promotions_after_version", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_version = ::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::get_own_promotions_after_version(&api_that, api_version).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_share_for_contact_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_get_share_for_contact", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_contact_id = ::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::get_share_for_contact(&api_that, api_contact_id).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_push_new_user_relation_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_push_new_user_relation", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_from_contact_id = ::sse_decode(&mut deserializer); +let api_announced_user = ::sse_decode(&mut deserializer); +let api_public_key_verified_timestamp = >::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::push_new_user_relation(&api_that, api_from_contact_id, api_announced_user, api_public_key_verified_timestamp).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_push_own_promotion_and_clear_old_version_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_push_own_promotion_and_clear_old_version", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_contact_id = ::sse_decode(&mut deserializer); +let api_version = ::sse_decode(&mut deserializer); +let api_promotion = >::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::push_own_promotion_and_clear_old_version(&api_that, api_contact_id, api_version, api_promotion).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_set_contact_version_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_set_contact_version", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_contact_id = ::sse_decode(&mut deserializer); +let api_update = >::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::set_contact_version(&api_that, api_contact_id, api_update).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_set_shares_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_set_shares", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_shares = >>::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::set_shares(&api_that, api_shares).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_store_other_promotion_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_store_other_promotion", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_promotion = ::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::store_other_promotion(&api_that, api_promotion).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_update_config_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_store_flutter_update_config", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_update = ::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::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter::update_config(&api_that, api_update).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_sign_data_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_utils_flutter_sign_data", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_input_data = >::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::bridge::callbacks::user_discovery::UserDiscoveryUtilsFlutter::sign_data(&api_that, &api_input_data).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_verify_signature_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_utils_flutter_verify_signature", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_input_data = >::sse_decode(&mut deserializer); +let api_pubkey = >::sse_decode(&mut deserializer); +let api_signature = >::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::bridge::callbacks::user_discovery::UserDiscoveryUtilsFlutter::verify_signature(&api_that, &api_input_data, &api_pubkey, &api_signature).await?; Ok(output_ok) + })().await) + } }) +} +fn wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_verify_stored_pubkey_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_async::(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "user_discovery_utils_flutter_verify_stored_pubkey", 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); + let api_that = ::sse_decode(&mut deserializer); +let api_from_contact_id = ::sse_decode(&mut deserializer); +let api_pubkey = >::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::bridge::callbacks::user_discovery::UserDiscoveryUtilsFlutter::verify_stored_pubkey(&api_that, api_from_contact_id, &api_pubkey).await?; Ok(output_ok) + })().await) + } }) +} // Section: static_checks @@ -1356,6 +1738,13 @@ impl SseDecode for crate::bridge::wrapper::key_manager::RustKeyManager { } } +impl SseDecode for crate::bridge::wrapper::RustUtils { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + return crate::bridge::wrapper::RustUtils {}; + } +} + 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 { @@ -1383,6 +1772,20 @@ impl SseDecode for () { fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {} } +impl SseDecode for crate::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + return crate::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter {}; + } +} + +impl SseDecode for crate::bridge::callbacks::user_discovery::UserDiscoveryUtilsFlutter { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + return crate::bridge::callbacks::user_discovery::UserDiscoveryUtilsFlutter {}; + } +} + impl SseDecode for usize { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -1431,8 +1834,27 @@ fn pde_ffi_dispatcher_primary_impl( 23 => wire__crate__bridge__wrapper__key_manager__rust_key_manager_load_signed_prekeys_impl(port, ptr, rust_vec_len, data_len), 24 => wire__crate__bridge__wrapper__key_manager__rust_key_manager_remove_key_manager_impl(port, ptr, rust_vec_len, data_len), 25 => wire__crate__bridge__wrapper__key_manager__rust_key_manager_remove_signed_prekey_impl(port, ptr, rust_vec_len, data_len), -26 => wire__crate__bridge__wrapper__key_manager__rust_key_manager_set_user_id_impl(port, ptr, rust_vec_len, data_len), -27 => wire__crate__bridge__wrapper__key_manager__rust_key_manager_store_signed_prekey_impl(port, ptr, rust_vec_len, data_len), +26 => wire__crate__bridge__wrapper__key_manager__rust_key_manager_serialize_impl(port, ptr, rust_vec_len, data_len), +27 => wire__crate__bridge__wrapper__key_manager__rust_key_manager_set_user_id_impl(port, ptr, rust_vec_len, data_len), +28 => wire__crate__bridge__wrapper__key_manager__rust_key_manager_store_signed_prekey_impl(port, ptr, rust_vec_len, data_len), +29 => wire__crate__bridge__wrapper__rust_utils_generate_shares_impl(port, ptr, rust_vec_len, data_len), +30 => wire__crate__bridge__wrapper__rust_utils_recover_secret_impl(port, ptr, rust_vec_len, data_len), +31 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_announced_user_by_public_id_impl(port, ptr, rust_vec_len, data_len), +32 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_config_impl(port, ptr, rust_vec_len, data_len), +33 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_contact_promotion_impl(port, ptr, rust_vec_len, data_len), +34 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_contact_version_impl(port, ptr, rust_vec_len, data_len), +35 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_other_promotions_by_public_id_impl(port, ptr, rust_vec_len, data_len), +36 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_own_promotions_after_version_impl(port, ptr, rust_vec_len, data_len), +37 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_share_for_contact_impl(port, ptr, rust_vec_len, data_len), +38 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_push_new_user_relation_impl(port, ptr, rust_vec_len, data_len), +39 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_push_own_promotion_and_clear_old_version_impl(port, ptr, rust_vec_len, data_len), +40 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_set_contact_version_impl(port, ptr, rust_vec_len, data_len), +41 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_set_shares_impl(port, ptr, rust_vec_len, data_len), +42 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_store_other_promotion_impl(port, ptr, rust_vec_len, data_len), +43 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_update_config_impl(port, ptr, rust_vec_len, data_len), +44 => wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_sign_data_impl(port, ptr, rust_vec_len, data_len), +45 => wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_verify_signature_impl(port, ptr, rust_vec_len, data_len), +46 => wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_verify_stored_pubkey_impl(port, ptr, rust_vec_len, data_len), _ => unreachable!(), } } @@ -1608,6 +2030,65 @@ impl flutter_rust_bridge::IntoIntoDart flutter_rust_bridge::for_generated::DartAbi { + Vec::::new().into_dart() + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive + for crate::bridge::wrapper::RustUtils +{ +} +impl flutter_rust_bridge::IntoIntoDart + for crate::bridge::wrapper::RustUtils +{ + fn into_into_dart(self) -> crate::bridge::wrapper::RustUtils { + self + } +} +// Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart + for crate::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter +{ + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + Vec::::new().into_dart() + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive + for crate::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter +{ +} +impl + flutter_rust_bridge::IntoIntoDart< + crate::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter, + > for crate::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter +{ + fn into_into_dart(self) -> crate::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter { + self + } +} +// Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart + for crate::bridge::callbacks::user_discovery::UserDiscoveryUtilsFlutter +{ + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + Vec::::new().into_dart() + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive + for crate::bridge::callbacks::user_discovery::UserDiscoveryUtilsFlutter +{ +} +impl + flutter_rust_bridge::IntoIntoDart< + crate::bridge::callbacks::user_discovery::UserDiscoveryUtilsFlutter, + > for crate::bridge::callbacks::user_discovery::UserDiscoveryUtilsFlutter +{ + fn into_into_dart(self) -> crate::bridge::callbacks::user_discovery::UserDiscoveryUtilsFlutter { + self + } +} impl SseEncode for flutter_rust_bridge::for_generated::anyhow::Error { // Codec=Sse (Serialization based), see doc to use other codecs @@ -1849,6 +2330,11 @@ impl SseEncode for crate::bridge::wrapper::key_manager::RustKeyManager { fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {} } +impl SseEncode for crate::bridge::wrapper::RustUtils { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {} +} + 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) { @@ -1881,6 +2367,16 @@ impl SseEncode for () { fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {} } +impl SseEncode for crate::bridge::callbacks::user_discovery::UserDiscoveryStoreFlutter { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {} +} + +impl SseEncode for crate::bridge::callbacks::user_discovery::UserDiscoveryUtilsFlutter { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {} +} + impl SseEncode for usize { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { @@ -1906,6 +2402,8 @@ mod io { // Section: imports use super::*; + use crate::user_discovery::traits::UserDiscoveryStore; + use crate::user_discovery::traits::UserDiscoveryUtils; use flutter_rust_bridge::for_generated::byteorder::{ NativeEndian, ReadBytesExt, WriteBytesExt, }; @@ -1928,6 +2426,8 @@ mod web { // Section: imports use super::*; + use crate::user_discovery::traits::UserDiscoveryStore; + use crate::user_discovery::traits::UserDiscoveryUtils; use flutter_rust_bridge::for_generated::byteorder::{ NativeEndian, ReadBytesExt, WriteBytesExt, }; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 4792ba90..5f12e840 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -6,7 +6,6 @@ mod error; mod frb_generated; mod keys; mod log; -mod passwordless_recovery; mod secure_storage; mod standalone; mod user_discovery; diff --git a/rust/src/passwordless_recovery/mod.rs b/rust/src/passwordless_recovery/mod.rs deleted file mode 100644 index 1eac912e..00000000 --- a/rust/src/passwordless_recovery/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -include!(concat!(env!("OUT_DIR"), "/passwordless_recovery.rs")); - -struct PasswordLessRecovery {} - -impl PasswordLessRecovery { - pub(crate) fn create_shared_secret_data( - total_shares: i64, - threshold: i64, - pin_unlock_token: Option>, - ) { - } -} diff --git a/scripts/generate_proto.sh b/scripts/generate_proto.sh index e1fafef8..52309111 100755 --- a/scripts/generate_proto.sh +++ b/scripts/generate_proto.sh @@ -16,13 +16,11 @@ protoc --proto_path="$CLIENT_DIR" --dart_out="$GENERATED_DIR" "messages.proto" protoc --proto_path="$CLIENT_DIR" --dart_out="$GENERATED_DIR" "groups.proto" protoc --proto_path="$CLIENT_DIR" --dart_out="$GENERATED_DIR" "qr.proto" protoc --proto_path="$CLIENT_DIR" --dart_out="$GENERATED_DIR" "data.proto" +protoc --proto_path="$CLIENT_DIR" --dart_out="$GENERATED_DIR" "passwordless_recovery.proto" mkdir "$GENERATED_DIR/user_discovery/" &>/dev/null protoc --proto_path="./rust/src/user_discovery/" --dart_out="$GENERATED_DIR/user_discovery/" "types.proto" -mkdir "$GENERATED_DIR/passwordless_recovery/" &>/dev/null -protoc --proto_path="./rust/src/passwordless_recovery/" --dart_out="$GENERATED_DIR/passwordless_recovery/" "types.proto" - protoc --proto_path="$CLIENT_DIR" --dart_out="$GENERATED_DIR" "push_notification.proto" protoc --proto_path="$CLIENT_DIR" --swift_out="./ios/NotificationService/" "push_notification.proto" diff --git a/test/drift/twonly_db/generated/schema.dart b/test/drift/twonly_db/generated/schema.dart index b7c0f66f..741be731 100644 --- a/test/drift/twonly_db/generated/schema.dart +++ b/test/drift/twonly_db/generated/schema.dart @@ -24,6 +24,7 @@ import 'schema_v17.dart' as v17; import 'schema_v18.dart' as v18; import 'schema_v19.dart' as v19; import 'schema_v20.dart' as v20; +import 'schema_v21.dart' as v21; class GeneratedHelper implements SchemaInstantiationHelper { @override @@ -69,6 +70,8 @@ class GeneratedHelper implements SchemaInstantiationHelper { return v19.DatabaseAtV19(db); case 20: return v20.DatabaseAtV20(db); + case 21: + return v21.DatabaseAtV21(db); default: throw MissingSchemaException(version, versions); } @@ -95,5 +98,6 @@ class GeneratedHelper implements SchemaInstantiationHelper { 18, 19, 20, + 21, ]; } diff --git a/test/drift/twonly_db/generated/schema_v21.dart b/test/drift/twonly_db/generated/schema_v21.dart new file mode 100644 index 00000000..6e2e20e6 --- /dev/null +++ b/test/drift/twonly_db/generated/schema_v21.dart @@ -0,0 +1,11000 @@ +// dart format width=80 +import 'dart:typed_data' as i2; +// GENERATED BY drift_dev, DO NOT MODIFY. +// ignore_for_file: type=lint,unused_import +// +import 'package:drift/drift.dart'; + +class Contacts extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + Contacts(this.attachedDatabase, [this._alias]); + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn username = GeneratedColumn( + 'username', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn displayName = GeneratedColumn( + 'display_name', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn nickName = GeneratedColumn( + 'nick_name', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn avatarSvgCompressed = + GeneratedColumn( + 'avatar_svg_compressed', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn senderProfileCounter = GeneratedColumn( + 'sender_profile_counter', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn accepted = GeneratedColumn( + 'accepted', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (accepted IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn deletedByUser = GeneratedColumn( + 'deleted_by_user', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (deleted_by_user IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn requested = GeneratedColumn( + 'requested', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (requested IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn blocked = GeneratedColumn( + 'blocked', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (blocked IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn verified = GeneratedColumn( + 'verified', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (verified IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn accountDeleted = GeneratedColumn( + 'account_deleted', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (account_deleted IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + late final GeneratedColumn userDiscoveryVersion = + GeneratedColumn( + 'user_discovery_version', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn userDiscoveryExcluded = GeneratedColumn( + 'user_discovery_excluded', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 CHECK (user_discovery_excluded IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn userDiscoveryManualApproved = + GeneratedColumn( + 'user_discovery_manual_approved', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NULL DEFAULT 0 CHECK (user_discovery_manual_approved IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn recoveryIsTrustedFriend = + GeneratedColumn( + 'recovery_is_trusted_friend', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 CHECK (recovery_is_trusted_friend IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn recoveryLastHeartbeat = GeneratedColumn( + 'recovery_last_heartbeat', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn recoverySecretShare = + GeneratedColumn( + 'recovery_secret_share', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn recoveryContactsSecretShare = + GeneratedColumn( + 'recovery_contacts_secret_share', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn recoveryContactsLastHeartbeat = + GeneratedColumn( + 'recovery_contacts_last_heartbeat', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn askForFriendPromotions = GeneratedColumn( + 'ask_for_friend_promotions', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL CHECK (ask_for_friend_promotions IN (0, 1))', + ); + late final GeneratedColumn mediaSendCounter = GeneratedColumn( + 'media_send_counter', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn mediaReceivedCounter = GeneratedColumn( + 'media_received_counter', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [ + userId, + username, + displayName, + nickName, + avatarSvgCompressed, + senderProfileCounter, + accepted, + deletedByUser, + requested, + blocked, + verified, + accountDeleted, + createdAt, + userDiscoveryVersion, + userDiscoveryExcluded, + userDiscoveryManualApproved, + recoveryIsTrustedFriend, + recoveryLastHeartbeat, + recoverySecretShare, + recoveryContactsSecretShare, + recoveryContactsLastHeartbeat, + askForFriendPromotions, + mediaSendCounter, + mediaReceivedCounter, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'contacts'; + @override + Set get $primaryKey => {userId}; + @override + ContactsData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return ContactsData( + userId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}user_id'], + )!, + username: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}username'], + )!, + displayName: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}display_name'], + ), + nickName: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}nick_name'], + ), + avatarSvgCompressed: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}avatar_svg_compressed'], + ), + senderProfileCounter: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}sender_profile_counter'], + )!, + accepted: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}accepted'], + )!, + deletedByUser: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}deleted_by_user'], + )!, + requested: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}requested'], + )!, + blocked: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}blocked'], + )!, + verified: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}verified'], + )!, + accountDeleted: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}account_deleted'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + userDiscoveryVersion: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}user_discovery_version'], + ), + userDiscoveryExcluded: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}user_discovery_excluded'], + )!, + userDiscoveryManualApproved: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}user_discovery_manual_approved'], + ), + recoveryIsTrustedFriend: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}recovery_is_trusted_friend'], + )!, + recoveryLastHeartbeat: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}recovery_last_heartbeat'], + ), + recoverySecretShare: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}recovery_secret_share'], + ), + recoveryContactsSecretShare: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}recovery_contacts_secret_share'], + ), + recoveryContactsLastHeartbeat: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}recovery_contacts_last_heartbeat'], + ), + askForFriendPromotions: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}ask_for_friend_promotions'], + ), + mediaSendCounter: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}media_send_counter'], + )!, + mediaReceivedCounter: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}media_received_counter'], + )!, + ); + } + + @override + Contacts createAlias(String alias) { + return Contacts(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(user_id)']; + @override + bool get dontWriteConstraints => true; +} + +class ContactsData extends DataClass implements Insertable { + final int userId; + final String username; + final String? displayName; + final String? nickName; + final i2.Uint8List? avatarSvgCompressed; + final int senderProfileCounter; + final int accepted; + final int deletedByUser; + final int requested; + final int blocked; + final int verified; + final int accountDeleted; + final int createdAt; + final i2.Uint8List? userDiscoveryVersion; + final int userDiscoveryExcluded; + final int? userDiscoveryManualApproved; + final int recoveryIsTrustedFriend; + final int? recoveryLastHeartbeat; + final i2.Uint8List? recoverySecretShare; + final i2.Uint8List? recoveryContactsSecretShare; + final int? recoveryContactsLastHeartbeat; + final int? askForFriendPromotions; + final int mediaSendCounter; + final int mediaReceivedCounter; + const ContactsData({ + required this.userId, + required this.username, + this.displayName, + this.nickName, + this.avatarSvgCompressed, + required this.senderProfileCounter, + required this.accepted, + required this.deletedByUser, + required this.requested, + required this.blocked, + required this.verified, + required this.accountDeleted, + required this.createdAt, + this.userDiscoveryVersion, + required this.userDiscoveryExcluded, + this.userDiscoveryManualApproved, + required this.recoveryIsTrustedFriend, + this.recoveryLastHeartbeat, + this.recoverySecretShare, + this.recoveryContactsSecretShare, + this.recoveryContactsLastHeartbeat, + this.askForFriendPromotions, + required this.mediaSendCounter, + required this.mediaReceivedCounter, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['user_id'] = Variable(userId); + map['username'] = Variable(username); + if (!nullToAbsent || displayName != null) { + map['display_name'] = Variable(displayName); + } + if (!nullToAbsent || nickName != null) { + map['nick_name'] = Variable(nickName); + } + if (!nullToAbsent || avatarSvgCompressed != null) { + map['avatar_svg_compressed'] = Variable( + avatarSvgCompressed, + ); + } + map['sender_profile_counter'] = Variable(senderProfileCounter); + map['accepted'] = Variable(accepted); + map['deleted_by_user'] = Variable(deletedByUser); + map['requested'] = Variable(requested); + map['blocked'] = Variable(blocked); + map['verified'] = Variable(verified); + map['account_deleted'] = Variable(accountDeleted); + map['created_at'] = Variable(createdAt); + if (!nullToAbsent || userDiscoveryVersion != null) { + map['user_discovery_version'] = Variable( + userDiscoveryVersion, + ); + } + map['user_discovery_excluded'] = Variable(userDiscoveryExcluded); + if (!nullToAbsent || userDiscoveryManualApproved != null) { + map['user_discovery_manual_approved'] = Variable( + userDiscoveryManualApproved, + ); + } + map['recovery_is_trusted_friend'] = Variable(recoveryIsTrustedFriend); + if (!nullToAbsent || recoveryLastHeartbeat != null) { + map['recovery_last_heartbeat'] = Variable(recoveryLastHeartbeat); + } + if (!nullToAbsent || recoverySecretShare != null) { + map['recovery_secret_share'] = Variable( + recoverySecretShare, + ); + } + if (!nullToAbsent || recoveryContactsSecretShare != null) { + map['recovery_contacts_secret_share'] = Variable( + recoveryContactsSecretShare, + ); + } + if (!nullToAbsent || recoveryContactsLastHeartbeat != null) { + map['recovery_contacts_last_heartbeat'] = Variable( + recoveryContactsLastHeartbeat, + ); + } + if (!nullToAbsent || askForFriendPromotions != null) { + map['ask_for_friend_promotions'] = Variable(askForFriendPromotions); + } + map['media_send_counter'] = Variable(mediaSendCounter); + map['media_received_counter'] = Variable(mediaReceivedCounter); + return map; + } + + ContactsCompanion toCompanion(bool nullToAbsent) { + return ContactsCompanion( + userId: Value(userId), + username: Value(username), + displayName: displayName == null && nullToAbsent + ? const Value.absent() + : Value(displayName), + nickName: nickName == null && nullToAbsent + ? const Value.absent() + : Value(nickName), + avatarSvgCompressed: avatarSvgCompressed == null && nullToAbsent + ? const Value.absent() + : Value(avatarSvgCompressed), + senderProfileCounter: Value(senderProfileCounter), + accepted: Value(accepted), + deletedByUser: Value(deletedByUser), + requested: Value(requested), + blocked: Value(blocked), + verified: Value(verified), + accountDeleted: Value(accountDeleted), + createdAt: Value(createdAt), + userDiscoveryVersion: userDiscoveryVersion == null && nullToAbsent + ? const Value.absent() + : Value(userDiscoveryVersion), + userDiscoveryExcluded: Value(userDiscoveryExcluded), + userDiscoveryManualApproved: + userDiscoveryManualApproved == null && nullToAbsent + ? const Value.absent() + : Value(userDiscoveryManualApproved), + recoveryIsTrustedFriend: Value(recoveryIsTrustedFriend), + recoveryLastHeartbeat: recoveryLastHeartbeat == null && nullToAbsent + ? const Value.absent() + : Value(recoveryLastHeartbeat), + recoverySecretShare: recoverySecretShare == null && nullToAbsent + ? const Value.absent() + : Value(recoverySecretShare), + recoveryContactsSecretShare: + recoveryContactsSecretShare == null && nullToAbsent + ? const Value.absent() + : Value(recoveryContactsSecretShare), + recoveryContactsLastHeartbeat: + recoveryContactsLastHeartbeat == null && nullToAbsent + ? const Value.absent() + : Value(recoveryContactsLastHeartbeat), + askForFriendPromotions: askForFriendPromotions == null && nullToAbsent + ? const Value.absent() + : Value(askForFriendPromotions), + mediaSendCounter: Value(mediaSendCounter), + mediaReceivedCounter: Value(mediaReceivedCounter), + ); + } + + factory ContactsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return ContactsData( + userId: serializer.fromJson(json['userId']), + username: serializer.fromJson(json['username']), + displayName: serializer.fromJson(json['displayName']), + nickName: serializer.fromJson(json['nickName']), + avatarSvgCompressed: serializer.fromJson( + json['avatarSvgCompressed'], + ), + senderProfileCounter: serializer.fromJson( + json['senderProfileCounter'], + ), + accepted: serializer.fromJson(json['accepted']), + deletedByUser: serializer.fromJson(json['deletedByUser']), + requested: serializer.fromJson(json['requested']), + blocked: serializer.fromJson(json['blocked']), + verified: serializer.fromJson(json['verified']), + accountDeleted: serializer.fromJson(json['accountDeleted']), + createdAt: serializer.fromJson(json['createdAt']), + userDiscoveryVersion: serializer.fromJson( + json['userDiscoveryVersion'], + ), + userDiscoveryExcluded: serializer.fromJson( + json['userDiscoveryExcluded'], + ), + userDiscoveryManualApproved: serializer.fromJson( + json['userDiscoveryManualApproved'], + ), + recoveryIsTrustedFriend: serializer.fromJson( + json['recoveryIsTrustedFriend'], + ), + recoveryLastHeartbeat: serializer.fromJson( + json['recoveryLastHeartbeat'], + ), + recoverySecretShare: serializer.fromJson( + json['recoverySecretShare'], + ), + recoveryContactsSecretShare: serializer.fromJson( + json['recoveryContactsSecretShare'], + ), + recoveryContactsLastHeartbeat: serializer.fromJson( + json['recoveryContactsLastHeartbeat'], + ), + askForFriendPromotions: serializer.fromJson( + json['askForFriendPromotions'], + ), + mediaSendCounter: serializer.fromJson(json['mediaSendCounter']), + mediaReceivedCounter: serializer.fromJson( + json['mediaReceivedCounter'], + ), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'userId': serializer.toJson(userId), + 'username': serializer.toJson(username), + 'displayName': serializer.toJson(displayName), + 'nickName': serializer.toJson(nickName), + 'avatarSvgCompressed': serializer.toJson( + avatarSvgCompressed, + ), + 'senderProfileCounter': serializer.toJson(senderProfileCounter), + 'accepted': serializer.toJson(accepted), + 'deletedByUser': serializer.toJson(deletedByUser), + 'requested': serializer.toJson(requested), + 'blocked': serializer.toJson(blocked), + 'verified': serializer.toJson(verified), + 'accountDeleted': serializer.toJson(accountDeleted), + 'createdAt': serializer.toJson(createdAt), + 'userDiscoveryVersion': serializer.toJson( + userDiscoveryVersion, + ), + 'userDiscoveryExcluded': serializer.toJson(userDiscoveryExcluded), + 'userDiscoveryManualApproved': serializer.toJson( + userDiscoveryManualApproved, + ), + 'recoveryIsTrustedFriend': serializer.toJson( + recoveryIsTrustedFriend, + ), + 'recoveryLastHeartbeat': serializer.toJson(recoveryLastHeartbeat), + 'recoverySecretShare': serializer.toJson( + recoverySecretShare, + ), + 'recoveryContactsSecretShare': serializer.toJson( + recoveryContactsSecretShare, + ), + 'recoveryContactsLastHeartbeat': serializer.toJson( + recoveryContactsLastHeartbeat, + ), + 'askForFriendPromotions': serializer.toJson(askForFriendPromotions), + 'mediaSendCounter': serializer.toJson(mediaSendCounter), + 'mediaReceivedCounter': serializer.toJson(mediaReceivedCounter), + }; + } + + ContactsData copyWith({ + int? userId, + String? username, + Value displayName = const Value.absent(), + Value nickName = const Value.absent(), + Value avatarSvgCompressed = const Value.absent(), + int? senderProfileCounter, + int? accepted, + int? deletedByUser, + int? requested, + int? blocked, + int? verified, + int? accountDeleted, + int? createdAt, + Value userDiscoveryVersion = const Value.absent(), + int? userDiscoveryExcluded, + Value userDiscoveryManualApproved = const Value.absent(), + int? recoveryIsTrustedFriend, + Value recoveryLastHeartbeat = const Value.absent(), + Value recoverySecretShare = const Value.absent(), + Value recoveryContactsSecretShare = const Value.absent(), + Value recoveryContactsLastHeartbeat = const Value.absent(), + Value askForFriendPromotions = const Value.absent(), + int? mediaSendCounter, + int? mediaReceivedCounter, + }) => ContactsData( + userId: userId ?? this.userId, + username: username ?? this.username, + displayName: displayName.present ? displayName.value : this.displayName, + nickName: nickName.present ? nickName.value : this.nickName, + avatarSvgCompressed: avatarSvgCompressed.present + ? avatarSvgCompressed.value + : this.avatarSvgCompressed, + senderProfileCounter: senderProfileCounter ?? this.senderProfileCounter, + accepted: accepted ?? this.accepted, + deletedByUser: deletedByUser ?? this.deletedByUser, + requested: requested ?? this.requested, + blocked: blocked ?? this.blocked, + verified: verified ?? this.verified, + accountDeleted: accountDeleted ?? this.accountDeleted, + createdAt: createdAt ?? this.createdAt, + userDiscoveryVersion: userDiscoveryVersion.present + ? userDiscoveryVersion.value + : this.userDiscoveryVersion, + userDiscoveryExcluded: userDiscoveryExcluded ?? this.userDiscoveryExcluded, + userDiscoveryManualApproved: userDiscoveryManualApproved.present + ? userDiscoveryManualApproved.value + : this.userDiscoveryManualApproved, + recoveryIsTrustedFriend: + recoveryIsTrustedFriend ?? this.recoveryIsTrustedFriend, + recoveryLastHeartbeat: recoveryLastHeartbeat.present + ? recoveryLastHeartbeat.value + : this.recoveryLastHeartbeat, + recoverySecretShare: recoverySecretShare.present + ? recoverySecretShare.value + : this.recoverySecretShare, + recoveryContactsSecretShare: recoveryContactsSecretShare.present + ? recoveryContactsSecretShare.value + : this.recoveryContactsSecretShare, + recoveryContactsLastHeartbeat: recoveryContactsLastHeartbeat.present + ? recoveryContactsLastHeartbeat.value + : this.recoveryContactsLastHeartbeat, + askForFriendPromotions: askForFriendPromotions.present + ? askForFriendPromotions.value + : this.askForFriendPromotions, + mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter, + mediaReceivedCounter: mediaReceivedCounter ?? this.mediaReceivedCounter, + ); + ContactsData copyWithCompanion(ContactsCompanion data) { + return ContactsData( + userId: data.userId.present ? data.userId.value : this.userId, + username: data.username.present ? data.username.value : this.username, + displayName: data.displayName.present + ? data.displayName.value + : this.displayName, + nickName: data.nickName.present ? data.nickName.value : this.nickName, + avatarSvgCompressed: data.avatarSvgCompressed.present + ? data.avatarSvgCompressed.value + : this.avatarSvgCompressed, + senderProfileCounter: data.senderProfileCounter.present + ? data.senderProfileCounter.value + : this.senderProfileCounter, + accepted: data.accepted.present ? data.accepted.value : this.accepted, + deletedByUser: data.deletedByUser.present + ? data.deletedByUser.value + : this.deletedByUser, + requested: data.requested.present ? data.requested.value : this.requested, + blocked: data.blocked.present ? data.blocked.value : this.blocked, + verified: data.verified.present ? data.verified.value : this.verified, + accountDeleted: data.accountDeleted.present + ? data.accountDeleted.value + : this.accountDeleted, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + userDiscoveryVersion: data.userDiscoveryVersion.present + ? data.userDiscoveryVersion.value + : this.userDiscoveryVersion, + userDiscoveryExcluded: data.userDiscoveryExcluded.present + ? data.userDiscoveryExcluded.value + : this.userDiscoveryExcluded, + userDiscoveryManualApproved: data.userDiscoveryManualApproved.present + ? data.userDiscoveryManualApproved.value + : this.userDiscoveryManualApproved, + recoveryIsTrustedFriend: data.recoveryIsTrustedFriend.present + ? data.recoveryIsTrustedFriend.value + : this.recoveryIsTrustedFriend, + recoveryLastHeartbeat: data.recoveryLastHeartbeat.present + ? data.recoveryLastHeartbeat.value + : this.recoveryLastHeartbeat, + recoverySecretShare: data.recoverySecretShare.present + ? data.recoverySecretShare.value + : this.recoverySecretShare, + recoveryContactsSecretShare: data.recoveryContactsSecretShare.present + ? data.recoveryContactsSecretShare.value + : this.recoveryContactsSecretShare, + recoveryContactsLastHeartbeat: data.recoveryContactsLastHeartbeat.present + ? data.recoveryContactsLastHeartbeat.value + : this.recoveryContactsLastHeartbeat, + askForFriendPromotions: data.askForFriendPromotions.present + ? data.askForFriendPromotions.value + : this.askForFriendPromotions, + mediaSendCounter: data.mediaSendCounter.present + ? data.mediaSendCounter.value + : this.mediaSendCounter, + mediaReceivedCounter: data.mediaReceivedCounter.present + ? data.mediaReceivedCounter.value + : this.mediaReceivedCounter, + ); + } + + @override + String toString() { + return (StringBuffer('ContactsData(') + ..write('userId: $userId, ') + ..write('username: $username, ') + ..write('displayName: $displayName, ') + ..write('nickName: $nickName, ') + ..write('avatarSvgCompressed: $avatarSvgCompressed, ') + ..write('senderProfileCounter: $senderProfileCounter, ') + ..write('accepted: $accepted, ') + ..write('deletedByUser: $deletedByUser, ') + ..write('requested: $requested, ') + ..write('blocked: $blocked, ') + ..write('verified: $verified, ') + ..write('accountDeleted: $accountDeleted, ') + ..write('createdAt: $createdAt, ') + ..write('userDiscoveryVersion: $userDiscoveryVersion, ') + ..write('userDiscoveryExcluded: $userDiscoveryExcluded, ') + ..write('userDiscoveryManualApproved: $userDiscoveryManualApproved, ') + ..write('recoveryIsTrustedFriend: $recoveryIsTrustedFriend, ') + ..write('recoveryLastHeartbeat: $recoveryLastHeartbeat, ') + ..write('recoverySecretShare: $recoverySecretShare, ') + ..write('recoveryContactsSecretShare: $recoveryContactsSecretShare, ') + ..write( + 'recoveryContactsLastHeartbeat: $recoveryContactsLastHeartbeat, ', + ) + ..write('askForFriendPromotions: $askForFriendPromotions, ') + ..write('mediaSendCounter: $mediaSendCounter, ') + ..write('mediaReceivedCounter: $mediaReceivedCounter') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hashAll([ + userId, + username, + displayName, + nickName, + $driftBlobEquality.hash(avatarSvgCompressed), + senderProfileCounter, + accepted, + deletedByUser, + requested, + blocked, + verified, + accountDeleted, + createdAt, + $driftBlobEquality.hash(userDiscoveryVersion), + userDiscoveryExcluded, + userDiscoveryManualApproved, + recoveryIsTrustedFriend, + recoveryLastHeartbeat, + $driftBlobEquality.hash(recoverySecretShare), + $driftBlobEquality.hash(recoveryContactsSecretShare), + recoveryContactsLastHeartbeat, + askForFriendPromotions, + mediaSendCounter, + mediaReceivedCounter, + ]); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is ContactsData && + other.userId == this.userId && + other.username == this.username && + other.displayName == this.displayName && + other.nickName == this.nickName && + $driftBlobEquality.equals( + other.avatarSvgCompressed, + this.avatarSvgCompressed, + ) && + other.senderProfileCounter == this.senderProfileCounter && + other.accepted == this.accepted && + other.deletedByUser == this.deletedByUser && + other.requested == this.requested && + other.blocked == this.blocked && + other.verified == this.verified && + other.accountDeleted == this.accountDeleted && + other.createdAt == this.createdAt && + $driftBlobEquality.equals( + other.userDiscoveryVersion, + this.userDiscoveryVersion, + ) && + other.userDiscoveryExcluded == this.userDiscoveryExcluded && + other.userDiscoveryManualApproved == + this.userDiscoveryManualApproved && + other.recoveryIsTrustedFriend == this.recoveryIsTrustedFriend && + other.recoveryLastHeartbeat == this.recoveryLastHeartbeat && + $driftBlobEquality.equals( + other.recoverySecretShare, + this.recoverySecretShare, + ) && + $driftBlobEquality.equals( + other.recoveryContactsSecretShare, + this.recoveryContactsSecretShare, + ) && + other.recoveryContactsLastHeartbeat == + this.recoveryContactsLastHeartbeat && + other.askForFriendPromotions == this.askForFriendPromotions && + other.mediaSendCounter == this.mediaSendCounter && + other.mediaReceivedCounter == this.mediaReceivedCounter); +} + +class ContactsCompanion extends UpdateCompanion { + final Value userId; + final Value username; + final Value displayName; + final Value nickName; + final Value avatarSvgCompressed; + final Value senderProfileCounter; + final Value accepted; + final Value deletedByUser; + final Value requested; + final Value blocked; + final Value verified; + final Value accountDeleted; + final Value createdAt; + final Value userDiscoveryVersion; + final Value userDiscoveryExcluded; + final Value userDiscoveryManualApproved; + final Value recoveryIsTrustedFriend; + final Value recoveryLastHeartbeat; + final Value recoverySecretShare; + final Value recoveryContactsSecretShare; + final Value recoveryContactsLastHeartbeat; + final Value askForFriendPromotions; + final Value mediaSendCounter; + final Value mediaReceivedCounter; + const ContactsCompanion({ + this.userId = const Value.absent(), + this.username = const Value.absent(), + this.displayName = const Value.absent(), + this.nickName = const Value.absent(), + this.avatarSvgCompressed = const Value.absent(), + this.senderProfileCounter = const Value.absent(), + this.accepted = const Value.absent(), + this.deletedByUser = const Value.absent(), + this.requested = const Value.absent(), + this.blocked = const Value.absent(), + this.verified = const Value.absent(), + this.accountDeleted = const Value.absent(), + this.createdAt = const Value.absent(), + this.userDiscoveryVersion = const Value.absent(), + this.userDiscoveryExcluded = const Value.absent(), + this.userDiscoveryManualApproved = const Value.absent(), + this.recoveryIsTrustedFriend = const Value.absent(), + this.recoveryLastHeartbeat = const Value.absent(), + this.recoverySecretShare = const Value.absent(), + this.recoveryContactsSecretShare = const Value.absent(), + this.recoveryContactsLastHeartbeat = const Value.absent(), + this.askForFriendPromotions = const Value.absent(), + this.mediaSendCounter = const Value.absent(), + this.mediaReceivedCounter = const Value.absent(), + }); + ContactsCompanion.insert({ + this.userId = const Value.absent(), + required String username, + this.displayName = const Value.absent(), + this.nickName = const Value.absent(), + this.avatarSvgCompressed = const Value.absent(), + this.senderProfileCounter = const Value.absent(), + this.accepted = const Value.absent(), + this.deletedByUser = const Value.absent(), + this.requested = const Value.absent(), + this.blocked = const Value.absent(), + this.verified = const Value.absent(), + this.accountDeleted = const Value.absent(), + this.createdAt = const Value.absent(), + this.userDiscoveryVersion = const Value.absent(), + this.userDiscoveryExcluded = const Value.absent(), + this.userDiscoveryManualApproved = const Value.absent(), + this.recoveryIsTrustedFriend = const Value.absent(), + this.recoveryLastHeartbeat = const Value.absent(), + this.recoverySecretShare = const Value.absent(), + this.recoveryContactsSecretShare = const Value.absent(), + this.recoveryContactsLastHeartbeat = const Value.absent(), + this.askForFriendPromotions = const Value.absent(), + this.mediaSendCounter = const Value.absent(), + this.mediaReceivedCounter = const Value.absent(), + }) : username = Value(username); + static Insertable custom({ + Expression? userId, + Expression? username, + Expression? displayName, + Expression? nickName, + Expression? avatarSvgCompressed, + Expression? senderProfileCounter, + Expression? accepted, + Expression? deletedByUser, + Expression? requested, + Expression? blocked, + Expression? verified, + Expression? accountDeleted, + Expression? createdAt, + Expression? userDiscoveryVersion, + Expression? userDiscoveryExcluded, + Expression? userDiscoveryManualApproved, + Expression? recoveryIsTrustedFriend, + Expression? recoveryLastHeartbeat, + Expression? recoverySecretShare, + Expression? recoveryContactsSecretShare, + Expression? recoveryContactsLastHeartbeat, + Expression? askForFriendPromotions, + Expression? mediaSendCounter, + Expression? mediaReceivedCounter, + }) { + return RawValuesInsertable({ + if (userId != null) 'user_id': userId, + if (username != null) 'username': username, + if (displayName != null) 'display_name': displayName, + if (nickName != null) 'nick_name': nickName, + if (avatarSvgCompressed != null) + 'avatar_svg_compressed': avatarSvgCompressed, + if (senderProfileCounter != null) + 'sender_profile_counter': senderProfileCounter, + if (accepted != null) 'accepted': accepted, + if (deletedByUser != null) 'deleted_by_user': deletedByUser, + if (requested != null) 'requested': requested, + if (blocked != null) 'blocked': blocked, + if (verified != null) 'verified': verified, + if (accountDeleted != null) 'account_deleted': accountDeleted, + if (createdAt != null) 'created_at': createdAt, + if (userDiscoveryVersion != null) + 'user_discovery_version': userDiscoveryVersion, + if (userDiscoveryExcluded != null) + 'user_discovery_excluded': userDiscoveryExcluded, + if (userDiscoveryManualApproved != null) + 'user_discovery_manual_approved': userDiscoveryManualApproved, + if (recoveryIsTrustedFriend != null) + 'recovery_is_trusted_friend': recoveryIsTrustedFriend, + if (recoveryLastHeartbeat != null) + 'recovery_last_heartbeat': recoveryLastHeartbeat, + if (recoverySecretShare != null) + 'recovery_secret_share': recoverySecretShare, + if (recoveryContactsSecretShare != null) + 'recovery_contacts_secret_share': recoveryContactsSecretShare, + if (recoveryContactsLastHeartbeat != null) + 'recovery_contacts_last_heartbeat': recoveryContactsLastHeartbeat, + if (askForFriendPromotions != null) + 'ask_for_friend_promotions': askForFriendPromotions, + if (mediaSendCounter != null) 'media_send_counter': mediaSendCounter, + if (mediaReceivedCounter != null) + 'media_received_counter': mediaReceivedCounter, + }); + } + + ContactsCompanion copyWith({ + Value? userId, + Value? username, + Value? displayName, + Value? nickName, + Value? avatarSvgCompressed, + Value? senderProfileCounter, + Value? accepted, + Value? deletedByUser, + Value? requested, + Value? blocked, + Value? verified, + Value? accountDeleted, + Value? createdAt, + Value? userDiscoveryVersion, + Value? userDiscoveryExcluded, + Value? userDiscoveryManualApproved, + Value? recoveryIsTrustedFriend, + Value? recoveryLastHeartbeat, + Value? recoverySecretShare, + Value? recoveryContactsSecretShare, + Value? recoveryContactsLastHeartbeat, + Value? askForFriendPromotions, + Value? mediaSendCounter, + Value? mediaReceivedCounter, + }) { + return ContactsCompanion( + userId: userId ?? this.userId, + username: username ?? this.username, + displayName: displayName ?? this.displayName, + nickName: nickName ?? this.nickName, + avatarSvgCompressed: avatarSvgCompressed ?? this.avatarSvgCompressed, + senderProfileCounter: senderProfileCounter ?? this.senderProfileCounter, + accepted: accepted ?? this.accepted, + deletedByUser: deletedByUser ?? this.deletedByUser, + requested: requested ?? this.requested, + blocked: blocked ?? this.blocked, + verified: verified ?? this.verified, + accountDeleted: accountDeleted ?? this.accountDeleted, + createdAt: createdAt ?? this.createdAt, + userDiscoveryVersion: userDiscoveryVersion ?? this.userDiscoveryVersion, + userDiscoveryExcluded: + userDiscoveryExcluded ?? this.userDiscoveryExcluded, + userDiscoveryManualApproved: + userDiscoveryManualApproved ?? this.userDiscoveryManualApproved, + recoveryIsTrustedFriend: + recoveryIsTrustedFriend ?? this.recoveryIsTrustedFriend, + recoveryLastHeartbeat: + recoveryLastHeartbeat ?? this.recoveryLastHeartbeat, + recoverySecretShare: recoverySecretShare ?? this.recoverySecretShare, + recoveryContactsSecretShare: + recoveryContactsSecretShare ?? this.recoveryContactsSecretShare, + recoveryContactsLastHeartbeat: + recoveryContactsLastHeartbeat ?? this.recoveryContactsLastHeartbeat, + askForFriendPromotions: + askForFriendPromotions ?? this.askForFriendPromotions, + mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter, + mediaReceivedCounter: mediaReceivedCounter ?? this.mediaReceivedCounter, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (userId.present) { + map['user_id'] = Variable(userId.value); + } + if (username.present) { + map['username'] = Variable(username.value); + } + if (displayName.present) { + map['display_name'] = Variable(displayName.value); + } + if (nickName.present) { + map['nick_name'] = Variable(nickName.value); + } + if (avatarSvgCompressed.present) { + map['avatar_svg_compressed'] = Variable( + avatarSvgCompressed.value, + ); + } + if (senderProfileCounter.present) { + map['sender_profile_counter'] = Variable(senderProfileCounter.value); + } + if (accepted.present) { + map['accepted'] = Variable(accepted.value); + } + if (deletedByUser.present) { + map['deleted_by_user'] = Variable(deletedByUser.value); + } + if (requested.present) { + map['requested'] = Variable(requested.value); + } + if (blocked.present) { + map['blocked'] = Variable(blocked.value); + } + if (verified.present) { + map['verified'] = Variable(verified.value); + } + if (accountDeleted.present) { + map['account_deleted'] = Variable(accountDeleted.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (userDiscoveryVersion.present) { + map['user_discovery_version'] = Variable( + userDiscoveryVersion.value, + ); + } + if (userDiscoveryExcluded.present) { + map['user_discovery_excluded'] = Variable( + userDiscoveryExcluded.value, + ); + } + if (userDiscoveryManualApproved.present) { + map['user_discovery_manual_approved'] = Variable( + userDiscoveryManualApproved.value, + ); + } + if (recoveryIsTrustedFriend.present) { + map['recovery_is_trusted_friend'] = Variable( + recoveryIsTrustedFriend.value, + ); + } + if (recoveryLastHeartbeat.present) { + map['recovery_last_heartbeat'] = Variable( + recoveryLastHeartbeat.value, + ); + } + if (recoverySecretShare.present) { + map['recovery_secret_share'] = Variable( + recoverySecretShare.value, + ); + } + if (recoveryContactsSecretShare.present) { + map['recovery_contacts_secret_share'] = Variable( + recoveryContactsSecretShare.value, + ); + } + if (recoveryContactsLastHeartbeat.present) { + map['recovery_contacts_last_heartbeat'] = Variable( + recoveryContactsLastHeartbeat.value, + ); + } + if (askForFriendPromotions.present) { + map['ask_for_friend_promotions'] = Variable( + askForFriendPromotions.value, + ); + } + if (mediaSendCounter.present) { + map['media_send_counter'] = Variable(mediaSendCounter.value); + } + if (mediaReceivedCounter.present) { + map['media_received_counter'] = Variable(mediaReceivedCounter.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('ContactsCompanion(') + ..write('userId: $userId, ') + ..write('username: $username, ') + ..write('displayName: $displayName, ') + ..write('nickName: $nickName, ') + ..write('avatarSvgCompressed: $avatarSvgCompressed, ') + ..write('senderProfileCounter: $senderProfileCounter, ') + ..write('accepted: $accepted, ') + ..write('deletedByUser: $deletedByUser, ') + ..write('requested: $requested, ') + ..write('blocked: $blocked, ') + ..write('verified: $verified, ') + ..write('accountDeleted: $accountDeleted, ') + ..write('createdAt: $createdAt, ') + ..write('userDiscoveryVersion: $userDiscoveryVersion, ') + ..write('userDiscoveryExcluded: $userDiscoveryExcluded, ') + ..write('userDiscoveryManualApproved: $userDiscoveryManualApproved, ') + ..write('recoveryIsTrustedFriend: $recoveryIsTrustedFriend, ') + ..write('recoveryLastHeartbeat: $recoveryLastHeartbeat, ') + ..write('recoverySecretShare: $recoverySecretShare, ') + ..write('recoveryContactsSecretShare: $recoveryContactsSecretShare, ') + ..write( + 'recoveryContactsLastHeartbeat: $recoveryContactsLastHeartbeat, ', + ) + ..write('askForFriendPromotions: $askForFriendPromotions, ') + ..write('mediaSendCounter: $mediaSendCounter, ') + ..write('mediaReceivedCounter: $mediaReceivedCounter') + ..write(')')) + .toString(); + } +} + +class Groups extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + Groups(this.attachedDatabase, [this._alias]); + late final GeneratedColumn groupId = GeneratedColumn( + 'group_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn isGroupAdmin = GeneratedColumn( + 'is_group_admin', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_group_admin IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn isDirectChat = GeneratedColumn( + 'is_direct_chat', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_direct_chat IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn pinned = GeneratedColumn( + 'pinned', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (pinned IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn archived = GeneratedColumn( + 'archived', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (archived IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn joinedGroup = GeneratedColumn( + 'joined_group', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (joined_group IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn leftGroup = GeneratedColumn( + 'left_group', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (left_group IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn deletedContent = GeneratedColumn( + 'deleted_content', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (deleted_content IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn stateVersionId = GeneratedColumn( + 'state_version_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn stateEncryptionKey = + GeneratedColumn( + 'state_encryption_key', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn myGroupPrivateKey = + GeneratedColumn( + 'my_group_private_key', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn groupName = GeneratedColumn( + 'group_name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn draftMessage = GeneratedColumn( + 'draft_message', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn totalMediaCounter = GeneratedColumn( + 'total_media_counter', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn alsoBestFriend = GeneratedColumn( + 'also_best_friend', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (also_best_friend IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn deleteMessagesAfterMilliseconds = + GeneratedColumn( + 'delete_messages_after_milliseconds', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 86400000', + defaultValue: const CustomExpression('86400000'), + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + late final GeneratedColumn lastMessageSend = GeneratedColumn( + 'last_message_send', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn lastMessageReceived = GeneratedColumn( + 'last_message_received', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn lastFlameCounterChange = GeneratedColumn( + 'last_flame_counter_change', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn lastFlameSync = GeneratedColumn( + 'last_flame_sync', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn flameCounter = GeneratedColumn( + 'flame_counter', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn maxFlameCounter = GeneratedColumn( + 'max_flame_counter', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn maxFlameCounterFrom = GeneratedColumn( + 'max_flame_counter_from', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn lastMessageExchange = GeneratedColumn( + 'last_message_exchange', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [ + groupId, + isGroupAdmin, + isDirectChat, + pinned, + archived, + joinedGroup, + leftGroup, + deletedContent, + stateVersionId, + stateEncryptionKey, + myGroupPrivateKey, + groupName, + draftMessage, + totalMediaCounter, + alsoBestFriend, + deleteMessagesAfterMilliseconds, + createdAt, + lastMessageSend, + lastMessageReceived, + lastFlameCounterChange, + lastFlameSync, + flameCounter, + maxFlameCounter, + maxFlameCounterFrom, + lastMessageExchange, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'groups'; + @override + Set get $primaryKey => {groupId}; + @override + GroupsData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return GroupsData( + groupId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}group_id'], + )!, + isGroupAdmin: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_group_admin'], + )!, + isDirectChat: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_direct_chat'], + )!, + pinned: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}pinned'], + )!, + archived: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}archived'], + )!, + joinedGroup: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}joined_group'], + )!, + leftGroup: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}left_group'], + )!, + deletedContent: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}deleted_content'], + )!, + stateVersionId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}state_version_id'], + )!, + stateEncryptionKey: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}state_encryption_key'], + ), + myGroupPrivateKey: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}my_group_private_key'], + ), + groupName: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}group_name'], + )!, + draftMessage: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}draft_message'], + ), + totalMediaCounter: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}total_media_counter'], + )!, + alsoBestFriend: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}also_best_friend'], + )!, + deleteMessagesAfterMilliseconds: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}delete_messages_after_milliseconds'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + lastMessageSend: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}last_message_send'], + ), + lastMessageReceived: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}last_message_received'], + ), + lastFlameCounterChange: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}last_flame_counter_change'], + ), + lastFlameSync: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}last_flame_sync'], + ), + flameCounter: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}flame_counter'], + )!, + maxFlameCounter: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}max_flame_counter'], + )!, + maxFlameCounterFrom: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}max_flame_counter_from'], + ), + lastMessageExchange: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}last_message_exchange'], + )!, + ); + } + + @override + Groups createAlias(String alias) { + return Groups(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(group_id)']; + @override + bool get dontWriteConstraints => true; +} + +class GroupsData extends DataClass implements Insertable { + final String groupId; + final int isGroupAdmin; + final int isDirectChat; + final int pinned; + final int archived; + final int joinedGroup; + final int leftGroup; + final int deletedContent; + final int stateVersionId; + final i2.Uint8List? stateEncryptionKey; + final i2.Uint8List? myGroupPrivateKey; + final String groupName; + final String? draftMessage; + final int totalMediaCounter; + final int alsoBestFriend; + final int deleteMessagesAfterMilliseconds; + final int createdAt; + final int? lastMessageSend; + final int? lastMessageReceived; + final int? lastFlameCounterChange; + final int? lastFlameSync; + final int flameCounter; + final int maxFlameCounter; + final int? maxFlameCounterFrom; + final int lastMessageExchange; + const GroupsData({ + required this.groupId, + required this.isGroupAdmin, + required this.isDirectChat, + required this.pinned, + required this.archived, + required this.joinedGroup, + required this.leftGroup, + required this.deletedContent, + required this.stateVersionId, + this.stateEncryptionKey, + this.myGroupPrivateKey, + required this.groupName, + this.draftMessage, + required this.totalMediaCounter, + required this.alsoBestFriend, + required this.deleteMessagesAfterMilliseconds, + required this.createdAt, + this.lastMessageSend, + this.lastMessageReceived, + this.lastFlameCounterChange, + this.lastFlameSync, + required this.flameCounter, + required this.maxFlameCounter, + this.maxFlameCounterFrom, + required this.lastMessageExchange, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['group_id'] = Variable(groupId); + map['is_group_admin'] = Variable(isGroupAdmin); + map['is_direct_chat'] = Variable(isDirectChat); + map['pinned'] = Variable(pinned); + map['archived'] = Variable(archived); + map['joined_group'] = Variable(joinedGroup); + map['left_group'] = Variable(leftGroup); + map['deleted_content'] = Variable(deletedContent); + map['state_version_id'] = Variable(stateVersionId); + if (!nullToAbsent || stateEncryptionKey != null) { + map['state_encryption_key'] = Variable(stateEncryptionKey); + } + if (!nullToAbsent || myGroupPrivateKey != null) { + map['my_group_private_key'] = Variable(myGroupPrivateKey); + } + map['group_name'] = Variable(groupName); + if (!nullToAbsent || draftMessage != null) { + map['draft_message'] = Variable(draftMessage); + } + map['total_media_counter'] = Variable(totalMediaCounter); + map['also_best_friend'] = Variable(alsoBestFriend); + map['delete_messages_after_milliseconds'] = Variable( + deleteMessagesAfterMilliseconds, + ); + map['created_at'] = Variable(createdAt); + if (!nullToAbsent || lastMessageSend != null) { + map['last_message_send'] = Variable(lastMessageSend); + } + if (!nullToAbsent || lastMessageReceived != null) { + map['last_message_received'] = Variable(lastMessageReceived); + } + if (!nullToAbsent || lastFlameCounterChange != null) { + map['last_flame_counter_change'] = Variable(lastFlameCounterChange); + } + if (!nullToAbsent || lastFlameSync != null) { + map['last_flame_sync'] = Variable(lastFlameSync); + } + map['flame_counter'] = Variable(flameCounter); + map['max_flame_counter'] = Variable(maxFlameCounter); + if (!nullToAbsent || maxFlameCounterFrom != null) { + map['max_flame_counter_from'] = Variable(maxFlameCounterFrom); + } + map['last_message_exchange'] = Variable(lastMessageExchange); + return map; + } + + GroupsCompanion toCompanion(bool nullToAbsent) { + return GroupsCompanion( + groupId: Value(groupId), + isGroupAdmin: Value(isGroupAdmin), + isDirectChat: Value(isDirectChat), + pinned: Value(pinned), + archived: Value(archived), + joinedGroup: Value(joinedGroup), + leftGroup: Value(leftGroup), + deletedContent: Value(deletedContent), + stateVersionId: Value(stateVersionId), + stateEncryptionKey: stateEncryptionKey == null && nullToAbsent + ? const Value.absent() + : Value(stateEncryptionKey), + myGroupPrivateKey: myGroupPrivateKey == null && nullToAbsent + ? const Value.absent() + : Value(myGroupPrivateKey), + groupName: Value(groupName), + draftMessage: draftMessage == null && nullToAbsent + ? const Value.absent() + : Value(draftMessage), + totalMediaCounter: Value(totalMediaCounter), + alsoBestFriend: Value(alsoBestFriend), + deleteMessagesAfterMilliseconds: Value(deleteMessagesAfterMilliseconds), + createdAt: Value(createdAt), + lastMessageSend: lastMessageSend == null && nullToAbsent + ? const Value.absent() + : Value(lastMessageSend), + lastMessageReceived: lastMessageReceived == null && nullToAbsent + ? const Value.absent() + : Value(lastMessageReceived), + lastFlameCounterChange: lastFlameCounterChange == null && nullToAbsent + ? const Value.absent() + : Value(lastFlameCounterChange), + lastFlameSync: lastFlameSync == null && nullToAbsent + ? const Value.absent() + : Value(lastFlameSync), + flameCounter: Value(flameCounter), + maxFlameCounter: Value(maxFlameCounter), + maxFlameCounterFrom: maxFlameCounterFrom == null && nullToAbsent + ? const Value.absent() + : Value(maxFlameCounterFrom), + lastMessageExchange: Value(lastMessageExchange), + ); + } + + factory GroupsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return GroupsData( + groupId: serializer.fromJson(json['groupId']), + isGroupAdmin: serializer.fromJson(json['isGroupAdmin']), + isDirectChat: serializer.fromJson(json['isDirectChat']), + pinned: serializer.fromJson(json['pinned']), + archived: serializer.fromJson(json['archived']), + joinedGroup: serializer.fromJson(json['joinedGroup']), + leftGroup: serializer.fromJson(json['leftGroup']), + deletedContent: serializer.fromJson(json['deletedContent']), + stateVersionId: serializer.fromJson(json['stateVersionId']), + stateEncryptionKey: serializer.fromJson( + json['stateEncryptionKey'], + ), + myGroupPrivateKey: serializer.fromJson( + json['myGroupPrivateKey'], + ), + groupName: serializer.fromJson(json['groupName']), + draftMessage: serializer.fromJson(json['draftMessage']), + totalMediaCounter: serializer.fromJson(json['totalMediaCounter']), + alsoBestFriend: serializer.fromJson(json['alsoBestFriend']), + deleteMessagesAfterMilliseconds: serializer.fromJson( + json['deleteMessagesAfterMilliseconds'], + ), + createdAt: serializer.fromJson(json['createdAt']), + lastMessageSend: serializer.fromJson(json['lastMessageSend']), + lastMessageReceived: serializer.fromJson( + json['lastMessageReceived'], + ), + lastFlameCounterChange: serializer.fromJson( + json['lastFlameCounterChange'], + ), + lastFlameSync: serializer.fromJson(json['lastFlameSync']), + flameCounter: serializer.fromJson(json['flameCounter']), + maxFlameCounter: serializer.fromJson(json['maxFlameCounter']), + maxFlameCounterFrom: serializer.fromJson( + json['maxFlameCounterFrom'], + ), + lastMessageExchange: serializer.fromJson( + json['lastMessageExchange'], + ), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'groupId': serializer.toJson(groupId), + 'isGroupAdmin': serializer.toJson(isGroupAdmin), + 'isDirectChat': serializer.toJson(isDirectChat), + 'pinned': serializer.toJson(pinned), + 'archived': serializer.toJson(archived), + 'joinedGroup': serializer.toJson(joinedGroup), + 'leftGroup': serializer.toJson(leftGroup), + 'deletedContent': serializer.toJson(deletedContent), + 'stateVersionId': serializer.toJson(stateVersionId), + 'stateEncryptionKey': serializer.toJson( + stateEncryptionKey, + ), + 'myGroupPrivateKey': serializer.toJson(myGroupPrivateKey), + 'groupName': serializer.toJson(groupName), + 'draftMessage': serializer.toJson(draftMessage), + 'totalMediaCounter': serializer.toJson(totalMediaCounter), + 'alsoBestFriend': serializer.toJson(alsoBestFriend), + 'deleteMessagesAfterMilliseconds': serializer.toJson( + deleteMessagesAfterMilliseconds, + ), + 'createdAt': serializer.toJson(createdAt), + 'lastMessageSend': serializer.toJson(lastMessageSend), + 'lastMessageReceived': serializer.toJson(lastMessageReceived), + 'lastFlameCounterChange': serializer.toJson(lastFlameCounterChange), + 'lastFlameSync': serializer.toJson(lastFlameSync), + 'flameCounter': serializer.toJson(flameCounter), + 'maxFlameCounter': serializer.toJson(maxFlameCounter), + 'maxFlameCounterFrom': serializer.toJson(maxFlameCounterFrom), + 'lastMessageExchange': serializer.toJson(lastMessageExchange), + }; + } + + GroupsData copyWith({ + String? groupId, + int? isGroupAdmin, + int? isDirectChat, + int? pinned, + int? archived, + int? joinedGroup, + int? leftGroup, + int? deletedContent, + int? stateVersionId, + Value stateEncryptionKey = const Value.absent(), + Value myGroupPrivateKey = const Value.absent(), + String? groupName, + Value draftMessage = const Value.absent(), + int? totalMediaCounter, + int? alsoBestFriend, + int? deleteMessagesAfterMilliseconds, + int? createdAt, + Value lastMessageSend = const Value.absent(), + Value lastMessageReceived = const Value.absent(), + Value lastFlameCounterChange = const Value.absent(), + Value lastFlameSync = const Value.absent(), + int? flameCounter, + int? maxFlameCounter, + Value maxFlameCounterFrom = const Value.absent(), + int? lastMessageExchange, + }) => GroupsData( + groupId: groupId ?? this.groupId, + isGroupAdmin: isGroupAdmin ?? this.isGroupAdmin, + isDirectChat: isDirectChat ?? this.isDirectChat, + pinned: pinned ?? this.pinned, + archived: archived ?? this.archived, + joinedGroup: joinedGroup ?? this.joinedGroup, + leftGroup: leftGroup ?? this.leftGroup, + deletedContent: deletedContent ?? this.deletedContent, + stateVersionId: stateVersionId ?? this.stateVersionId, + stateEncryptionKey: stateEncryptionKey.present + ? stateEncryptionKey.value + : this.stateEncryptionKey, + myGroupPrivateKey: myGroupPrivateKey.present + ? myGroupPrivateKey.value + : this.myGroupPrivateKey, + groupName: groupName ?? this.groupName, + draftMessage: draftMessage.present ? draftMessage.value : this.draftMessage, + totalMediaCounter: totalMediaCounter ?? this.totalMediaCounter, + alsoBestFriend: alsoBestFriend ?? this.alsoBestFriend, + deleteMessagesAfterMilliseconds: + deleteMessagesAfterMilliseconds ?? this.deleteMessagesAfterMilliseconds, + createdAt: createdAt ?? this.createdAt, + lastMessageSend: lastMessageSend.present + ? lastMessageSend.value + : this.lastMessageSend, + lastMessageReceived: lastMessageReceived.present + ? lastMessageReceived.value + : this.lastMessageReceived, + lastFlameCounterChange: lastFlameCounterChange.present + ? lastFlameCounterChange.value + : this.lastFlameCounterChange, + lastFlameSync: lastFlameSync.present + ? lastFlameSync.value + : this.lastFlameSync, + flameCounter: flameCounter ?? this.flameCounter, + maxFlameCounter: maxFlameCounter ?? this.maxFlameCounter, + maxFlameCounterFrom: maxFlameCounterFrom.present + ? maxFlameCounterFrom.value + : this.maxFlameCounterFrom, + lastMessageExchange: lastMessageExchange ?? this.lastMessageExchange, + ); + GroupsData copyWithCompanion(GroupsCompanion data) { + return GroupsData( + groupId: data.groupId.present ? data.groupId.value : this.groupId, + isGroupAdmin: data.isGroupAdmin.present + ? data.isGroupAdmin.value + : this.isGroupAdmin, + isDirectChat: data.isDirectChat.present + ? data.isDirectChat.value + : this.isDirectChat, + pinned: data.pinned.present ? data.pinned.value : this.pinned, + archived: data.archived.present ? data.archived.value : this.archived, + joinedGroup: data.joinedGroup.present + ? data.joinedGroup.value + : this.joinedGroup, + leftGroup: data.leftGroup.present ? data.leftGroup.value : this.leftGroup, + deletedContent: data.deletedContent.present + ? data.deletedContent.value + : this.deletedContent, + stateVersionId: data.stateVersionId.present + ? data.stateVersionId.value + : this.stateVersionId, + stateEncryptionKey: data.stateEncryptionKey.present + ? data.stateEncryptionKey.value + : this.stateEncryptionKey, + myGroupPrivateKey: data.myGroupPrivateKey.present + ? data.myGroupPrivateKey.value + : this.myGroupPrivateKey, + groupName: data.groupName.present ? data.groupName.value : this.groupName, + draftMessage: data.draftMessage.present + ? data.draftMessage.value + : this.draftMessage, + totalMediaCounter: data.totalMediaCounter.present + ? data.totalMediaCounter.value + : this.totalMediaCounter, + alsoBestFriend: data.alsoBestFriend.present + ? data.alsoBestFriend.value + : this.alsoBestFriend, + deleteMessagesAfterMilliseconds: + data.deleteMessagesAfterMilliseconds.present + ? data.deleteMessagesAfterMilliseconds.value + : this.deleteMessagesAfterMilliseconds, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + lastMessageSend: data.lastMessageSend.present + ? data.lastMessageSend.value + : this.lastMessageSend, + lastMessageReceived: data.lastMessageReceived.present + ? data.lastMessageReceived.value + : this.lastMessageReceived, + lastFlameCounterChange: data.lastFlameCounterChange.present + ? data.lastFlameCounterChange.value + : this.lastFlameCounterChange, + lastFlameSync: data.lastFlameSync.present + ? data.lastFlameSync.value + : this.lastFlameSync, + flameCounter: data.flameCounter.present + ? data.flameCounter.value + : this.flameCounter, + maxFlameCounter: data.maxFlameCounter.present + ? data.maxFlameCounter.value + : this.maxFlameCounter, + maxFlameCounterFrom: data.maxFlameCounterFrom.present + ? data.maxFlameCounterFrom.value + : this.maxFlameCounterFrom, + lastMessageExchange: data.lastMessageExchange.present + ? data.lastMessageExchange.value + : this.lastMessageExchange, + ); + } + + @override + String toString() { + return (StringBuffer('GroupsData(') + ..write('groupId: $groupId, ') + ..write('isGroupAdmin: $isGroupAdmin, ') + ..write('isDirectChat: $isDirectChat, ') + ..write('pinned: $pinned, ') + ..write('archived: $archived, ') + ..write('joinedGroup: $joinedGroup, ') + ..write('leftGroup: $leftGroup, ') + ..write('deletedContent: $deletedContent, ') + ..write('stateVersionId: $stateVersionId, ') + ..write('stateEncryptionKey: $stateEncryptionKey, ') + ..write('myGroupPrivateKey: $myGroupPrivateKey, ') + ..write('groupName: $groupName, ') + ..write('draftMessage: $draftMessage, ') + ..write('totalMediaCounter: $totalMediaCounter, ') + ..write('alsoBestFriend: $alsoBestFriend, ') + ..write( + 'deleteMessagesAfterMilliseconds: $deleteMessagesAfterMilliseconds, ', + ) + ..write('createdAt: $createdAt, ') + ..write('lastMessageSend: $lastMessageSend, ') + ..write('lastMessageReceived: $lastMessageReceived, ') + ..write('lastFlameCounterChange: $lastFlameCounterChange, ') + ..write('lastFlameSync: $lastFlameSync, ') + ..write('flameCounter: $flameCounter, ') + ..write('maxFlameCounter: $maxFlameCounter, ') + ..write('maxFlameCounterFrom: $maxFlameCounterFrom, ') + ..write('lastMessageExchange: $lastMessageExchange') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hashAll([ + groupId, + isGroupAdmin, + isDirectChat, + pinned, + archived, + joinedGroup, + leftGroup, + deletedContent, + stateVersionId, + $driftBlobEquality.hash(stateEncryptionKey), + $driftBlobEquality.hash(myGroupPrivateKey), + groupName, + draftMessage, + totalMediaCounter, + alsoBestFriend, + deleteMessagesAfterMilliseconds, + createdAt, + lastMessageSend, + lastMessageReceived, + lastFlameCounterChange, + lastFlameSync, + flameCounter, + maxFlameCounter, + maxFlameCounterFrom, + lastMessageExchange, + ]); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is GroupsData && + other.groupId == this.groupId && + other.isGroupAdmin == this.isGroupAdmin && + other.isDirectChat == this.isDirectChat && + other.pinned == this.pinned && + other.archived == this.archived && + other.joinedGroup == this.joinedGroup && + other.leftGroup == this.leftGroup && + other.deletedContent == this.deletedContent && + other.stateVersionId == this.stateVersionId && + $driftBlobEquality.equals( + other.stateEncryptionKey, + this.stateEncryptionKey, + ) && + $driftBlobEquality.equals( + other.myGroupPrivateKey, + this.myGroupPrivateKey, + ) && + other.groupName == this.groupName && + other.draftMessage == this.draftMessage && + other.totalMediaCounter == this.totalMediaCounter && + other.alsoBestFriend == this.alsoBestFriend && + other.deleteMessagesAfterMilliseconds == + this.deleteMessagesAfterMilliseconds && + other.createdAt == this.createdAt && + other.lastMessageSend == this.lastMessageSend && + other.lastMessageReceived == this.lastMessageReceived && + other.lastFlameCounterChange == this.lastFlameCounterChange && + other.lastFlameSync == this.lastFlameSync && + other.flameCounter == this.flameCounter && + other.maxFlameCounter == this.maxFlameCounter && + other.maxFlameCounterFrom == this.maxFlameCounterFrom && + other.lastMessageExchange == this.lastMessageExchange); +} + +class GroupsCompanion extends UpdateCompanion { + final Value groupId; + final Value isGroupAdmin; + final Value isDirectChat; + final Value pinned; + final Value archived; + final Value joinedGroup; + final Value leftGroup; + final Value deletedContent; + final Value stateVersionId; + final Value stateEncryptionKey; + final Value myGroupPrivateKey; + final Value groupName; + final Value draftMessage; + final Value totalMediaCounter; + final Value alsoBestFriend; + final Value deleteMessagesAfterMilliseconds; + final Value createdAt; + final Value lastMessageSend; + final Value lastMessageReceived; + final Value lastFlameCounterChange; + final Value lastFlameSync; + final Value flameCounter; + final Value maxFlameCounter; + final Value maxFlameCounterFrom; + final Value lastMessageExchange; + final Value rowid; + const GroupsCompanion({ + this.groupId = const Value.absent(), + this.isGroupAdmin = const Value.absent(), + this.isDirectChat = const Value.absent(), + this.pinned = const Value.absent(), + this.archived = const Value.absent(), + this.joinedGroup = const Value.absent(), + this.leftGroup = const Value.absent(), + this.deletedContent = const Value.absent(), + this.stateVersionId = const Value.absent(), + this.stateEncryptionKey = const Value.absent(), + this.myGroupPrivateKey = const Value.absent(), + this.groupName = const Value.absent(), + this.draftMessage = const Value.absent(), + this.totalMediaCounter = const Value.absent(), + this.alsoBestFriend = const Value.absent(), + this.deleteMessagesAfterMilliseconds = const Value.absent(), + this.createdAt = const Value.absent(), + this.lastMessageSend = const Value.absent(), + this.lastMessageReceived = const Value.absent(), + this.lastFlameCounterChange = const Value.absent(), + this.lastFlameSync = const Value.absent(), + this.flameCounter = const Value.absent(), + this.maxFlameCounter = const Value.absent(), + this.maxFlameCounterFrom = const Value.absent(), + this.lastMessageExchange = const Value.absent(), + this.rowid = const Value.absent(), + }); + GroupsCompanion.insert({ + required String groupId, + this.isGroupAdmin = const Value.absent(), + this.isDirectChat = const Value.absent(), + this.pinned = const Value.absent(), + this.archived = const Value.absent(), + this.joinedGroup = const Value.absent(), + this.leftGroup = const Value.absent(), + this.deletedContent = const Value.absent(), + this.stateVersionId = const Value.absent(), + this.stateEncryptionKey = const Value.absent(), + this.myGroupPrivateKey = const Value.absent(), + required String groupName, + this.draftMessage = const Value.absent(), + this.totalMediaCounter = const Value.absent(), + this.alsoBestFriend = const Value.absent(), + this.deleteMessagesAfterMilliseconds = const Value.absent(), + this.createdAt = const Value.absent(), + this.lastMessageSend = const Value.absent(), + this.lastMessageReceived = const Value.absent(), + this.lastFlameCounterChange = const Value.absent(), + this.lastFlameSync = const Value.absent(), + this.flameCounter = const Value.absent(), + this.maxFlameCounter = const Value.absent(), + this.maxFlameCounterFrom = const Value.absent(), + this.lastMessageExchange = const Value.absent(), + this.rowid = const Value.absent(), + }) : groupId = Value(groupId), + groupName = Value(groupName); + static Insertable custom({ + Expression? groupId, + Expression? isGroupAdmin, + Expression? isDirectChat, + Expression? pinned, + Expression? archived, + Expression? joinedGroup, + Expression? leftGroup, + Expression? deletedContent, + Expression? stateVersionId, + Expression? stateEncryptionKey, + Expression? myGroupPrivateKey, + Expression? groupName, + Expression? draftMessage, + Expression? totalMediaCounter, + Expression? alsoBestFriend, + Expression? deleteMessagesAfterMilliseconds, + Expression? createdAt, + Expression? lastMessageSend, + Expression? lastMessageReceived, + Expression? lastFlameCounterChange, + Expression? lastFlameSync, + Expression? flameCounter, + Expression? maxFlameCounter, + Expression? maxFlameCounterFrom, + Expression? lastMessageExchange, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (groupId != null) 'group_id': groupId, + if (isGroupAdmin != null) 'is_group_admin': isGroupAdmin, + if (isDirectChat != null) 'is_direct_chat': isDirectChat, + if (pinned != null) 'pinned': pinned, + if (archived != null) 'archived': archived, + if (joinedGroup != null) 'joined_group': joinedGroup, + if (leftGroup != null) 'left_group': leftGroup, + if (deletedContent != null) 'deleted_content': deletedContent, + if (stateVersionId != null) 'state_version_id': stateVersionId, + if (stateEncryptionKey != null) + 'state_encryption_key': stateEncryptionKey, + if (myGroupPrivateKey != null) 'my_group_private_key': myGroupPrivateKey, + if (groupName != null) 'group_name': groupName, + if (draftMessage != null) 'draft_message': draftMessage, + if (totalMediaCounter != null) 'total_media_counter': totalMediaCounter, + if (alsoBestFriend != null) 'also_best_friend': alsoBestFriend, + if (deleteMessagesAfterMilliseconds != null) + 'delete_messages_after_milliseconds': deleteMessagesAfterMilliseconds, + if (createdAt != null) 'created_at': createdAt, + if (lastMessageSend != null) 'last_message_send': lastMessageSend, + if (lastMessageReceived != null) + 'last_message_received': lastMessageReceived, + if (lastFlameCounterChange != null) + 'last_flame_counter_change': lastFlameCounterChange, + if (lastFlameSync != null) 'last_flame_sync': lastFlameSync, + if (flameCounter != null) 'flame_counter': flameCounter, + if (maxFlameCounter != null) 'max_flame_counter': maxFlameCounter, + if (maxFlameCounterFrom != null) + 'max_flame_counter_from': maxFlameCounterFrom, + if (lastMessageExchange != null) + 'last_message_exchange': lastMessageExchange, + if (rowid != null) 'rowid': rowid, + }); + } + + GroupsCompanion copyWith({ + Value? groupId, + Value? isGroupAdmin, + Value? isDirectChat, + Value? pinned, + Value? archived, + Value? joinedGroup, + Value? leftGroup, + Value? deletedContent, + Value? stateVersionId, + Value? stateEncryptionKey, + Value? myGroupPrivateKey, + Value? groupName, + Value? draftMessage, + Value? totalMediaCounter, + Value? alsoBestFriend, + Value? deleteMessagesAfterMilliseconds, + Value? createdAt, + Value? lastMessageSend, + Value? lastMessageReceived, + Value? lastFlameCounterChange, + Value? lastFlameSync, + Value? flameCounter, + Value? maxFlameCounter, + Value? maxFlameCounterFrom, + Value? lastMessageExchange, + Value? rowid, + }) { + return GroupsCompanion( + groupId: groupId ?? this.groupId, + isGroupAdmin: isGroupAdmin ?? this.isGroupAdmin, + isDirectChat: isDirectChat ?? this.isDirectChat, + pinned: pinned ?? this.pinned, + archived: archived ?? this.archived, + joinedGroup: joinedGroup ?? this.joinedGroup, + leftGroup: leftGroup ?? this.leftGroup, + deletedContent: deletedContent ?? this.deletedContent, + stateVersionId: stateVersionId ?? this.stateVersionId, + stateEncryptionKey: stateEncryptionKey ?? this.stateEncryptionKey, + myGroupPrivateKey: myGroupPrivateKey ?? this.myGroupPrivateKey, + groupName: groupName ?? this.groupName, + draftMessage: draftMessage ?? this.draftMessage, + totalMediaCounter: totalMediaCounter ?? this.totalMediaCounter, + alsoBestFriend: alsoBestFriend ?? this.alsoBestFriend, + deleteMessagesAfterMilliseconds: + deleteMessagesAfterMilliseconds ?? + this.deleteMessagesAfterMilliseconds, + createdAt: createdAt ?? this.createdAt, + lastMessageSend: lastMessageSend ?? this.lastMessageSend, + lastMessageReceived: lastMessageReceived ?? this.lastMessageReceived, + lastFlameCounterChange: + lastFlameCounterChange ?? this.lastFlameCounterChange, + lastFlameSync: lastFlameSync ?? this.lastFlameSync, + flameCounter: flameCounter ?? this.flameCounter, + maxFlameCounter: maxFlameCounter ?? this.maxFlameCounter, + maxFlameCounterFrom: maxFlameCounterFrom ?? this.maxFlameCounterFrom, + lastMessageExchange: lastMessageExchange ?? this.lastMessageExchange, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (groupId.present) { + map['group_id'] = Variable(groupId.value); + } + if (isGroupAdmin.present) { + map['is_group_admin'] = Variable(isGroupAdmin.value); + } + if (isDirectChat.present) { + map['is_direct_chat'] = Variable(isDirectChat.value); + } + if (pinned.present) { + map['pinned'] = Variable(pinned.value); + } + if (archived.present) { + map['archived'] = Variable(archived.value); + } + if (joinedGroup.present) { + map['joined_group'] = Variable(joinedGroup.value); + } + if (leftGroup.present) { + map['left_group'] = Variable(leftGroup.value); + } + if (deletedContent.present) { + map['deleted_content'] = Variable(deletedContent.value); + } + if (stateVersionId.present) { + map['state_version_id'] = Variable(stateVersionId.value); + } + if (stateEncryptionKey.present) { + map['state_encryption_key'] = Variable( + stateEncryptionKey.value, + ); + } + if (myGroupPrivateKey.present) { + map['my_group_private_key'] = Variable( + myGroupPrivateKey.value, + ); + } + if (groupName.present) { + map['group_name'] = Variable(groupName.value); + } + if (draftMessage.present) { + map['draft_message'] = Variable(draftMessage.value); + } + if (totalMediaCounter.present) { + map['total_media_counter'] = Variable(totalMediaCounter.value); + } + if (alsoBestFriend.present) { + map['also_best_friend'] = Variable(alsoBestFriend.value); + } + if (deleteMessagesAfterMilliseconds.present) { + map['delete_messages_after_milliseconds'] = Variable( + deleteMessagesAfterMilliseconds.value, + ); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (lastMessageSend.present) { + map['last_message_send'] = Variable(lastMessageSend.value); + } + if (lastMessageReceived.present) { + map['last_message_received'] = Variable(lastMessageReceived.value); + } + if (lastFlameCounterChange.present) { + map['last_flame_counter_change'] = Variable( + lastFlameCounterChange.value, + ); + } + if (lastFlameSync.present) { + map['last_flame_sync'] = Variable(lastFlameSync.value); + } + if (flameCounter.present) { + map['flame_counter'] = Variable(flameCounter.value); + } + if (maxFlameCounter.present) { + map['max_flame_counter'] = Variable(maxFlameCounter.value); + } + if (maxFlameCounterFrom.present) { + map['max_flame_counter_from'] = Variable(maxFlameCounterFrom.value); + } + if (lastMessageExchange.present) { + map['last_message_exchange'] = Variable(lastMessageExchange.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('GroupsCompanion(') + ..write('groupId: $groupId, ') + ..write('isGroupAdmin: $isGroupAdmin, ') + ..write('isDirectChat: $isDirectChat, ') + ..write('pinned: $pinned, ') + ..write('archived: $archived, ') + ..write('joinedGroup: $joinedGroup, ') + ..write('leftGroup: $leftGroup, ') + ..write('deletedContent: $deletedContent, ') + ..write('stateVersionId: $stateVersionId, ') + ..write('stateEncryptionKey: $stateEncryptionKey, ') + ..write('myGroupPrivateKey: $myGroupPrivateKey, ') + ..write('groupName: $groupName, ') + ..write('draftMessage: $draftMessage, ') + ..write('totalMediaCounter: $totalMediaCounter, ') + ..write('alsoBestFriend: $alsoBestFriend, ') + ..write( + 'deleteMessagesAfterMilliseconds: $deleteMessagesAfterMilliseconds, ', + ) + ..write('createdAt: $createdAt, ') + ..write('lastMessageSend: $lastMessageSend, ') + ..write('lastMessageReceived: $lastMessageReceived, ') + ..write('lastFlameCounterChange: $lastFlameCounterChange, ') + ..write('lastFlameSync: $lastFlameSync, ') + ..write('flameCounter: $flameCounter, ') + ..write('maxFlameCounter: $maxFlameCounter, ') + ..write('maxFlameCounterFrom: $maxFlameCounterFrom, ') + ..write('lastMessageExchange: $lastMessageExchange, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class MediaFiles extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + MediaFiles(this.attachedDatabase, [this._alias]); + late final GeneratedColumn mediaId = GeneratedColumn( + 'media_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn uploadState = GeneratedColumn( + 'upload_state', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn downloadState = GeneratedColumn( + 'download_state', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn requiresAuthentication = GeneratedColumn( + 'requires_authentication', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 CHECK (requires_authentication IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn stored = GeneratedColumn( + 'stored', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK ("stored" IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn isDraftMedia = GeneratedColumn( + 'is_draft_media', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_draft_media IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_favorite IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn hasCropAnalyzed = GeneratedColumn( + 'has_crop_analyzed', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 CHECK (has_crop_analyzed IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn preProgressingProcess = GeneratedColumn( + 'pre_progressing_process', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn reuploadRequestedBy = + GeneratedColumn( + 'reupload_requested_by', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn displayLimitInMilliseconds = + GeneratedColumn( + 'display_limit_in_milliseconds', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn removeAudio = GeneratedColumn( + 'remove_audio', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL CHECK (remove_audio IN (0, 1))', + ); + late final GeneratedColumn downloadToken = + GeneratedColumn( + 'download_token', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn encryptionKey = + GeneratedColumn( + 'encryption_key', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn encryptionMac = + GeneratedColumn( + 'encryption_mac', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn encryptionNonce = + GeneratedColumn( + 'encryption_nonce', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn storedFileHash = + GeneratedColumn( + 'stored_file_hash', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn hasThumbnail = GeneratedColumn( + 'has_thumbnail', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (has_thumbnail IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn sizeInBytes = GeneratedColumn( + 'size_in_bytes', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + late final GeneratedColumn createdAtMonth = GeneratedColumn( + 'created_at_month', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + @override + List get $columns => [ + mediaId, + type, + uploadState, + downloadState, + requiresAuthentication, + stored, + isDraftMedia, + isFavorite, + hasCropAnalyzed, + preProgressingProcess, + reuploadRequestedBy, + displayLimitInMilliseconds, + removeAudio, + downloadToken, + encryptionKey, + encryptionMac, + encryptionNonce, + storedFileHash, + hasThumbnail, + sizeInBytes, + createdAt, + createdAtMonth, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'media_files'; + @override + Set get $primaryKey => {mediaId}; + @override + MediaFilesData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return MediaFilesData( + mediaId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}media_id'], + )!, + type: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}type'], + )!, + uploadState: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}upload_state'], + ), + downloadState: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}download_state'], + ), + requiresAuthentication: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}requires_authentication'], + )!, + stored: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}stored'], + )!, + isDraftMedia: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_draft_media'], + )!, + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_favorite'], + )!, + hasCropAnalyzed: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}has_crop_analyzed'], + )!, + preProgressingProcess: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}pre_progressing_process'], + ), + reuploadRequestedBy: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}reupload_requested_by'], + ), + displayLimitInMilliseconds: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}display_limit_in_milliseconds'], + ), + removeAudio: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}remove_audio'], + ), + downloadToken: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}download_token'], + ), + encryptionKey: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}encryption_key'], + ), + encryptionMac: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}encryption_mac'], + ), + encryptionNonce: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}encryption_nonce'], + ), + storedFileHash: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}stored_file_hash'], + ), + hasThumbnail: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}has_thumbnail'], + )!, + sizeInBytes: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}size_in_bytes'], + ), + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + createdAtMonth: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}created_at_month'], + ), + ); + } + + @override + MediaFiles createAlias(String alias) { + return MediaFiles(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(media_id)']; + @override + bool get dontWriteConstraints => true; +} + +class MediaFilesData extends DataClass implements Insertable { + final String mediaId; + final String type; + final String? uploadState; + final String? downloadState; + final int requiresAuthentication; + final int stored; + final int isDraftMedia; + final int isFavorite; + final int hasCropAnalyzed; + final int? preProgressingProcess; + final String? reuploadRequestedBy; + final int? displayLimitInMilliseconds; + final int? removeAudio; + final i2.Uint8List? downloadToken; + final i2.Uint8List? encryptionKey; + final i2.Uint8List? encryptionMac; + final i2.Uint8List? encryptionNonce; + final i2.Uint8List? storedFileHash; + final int hasThumbnail; + final int? sizeInBytes; + final int createdAt; + final String? createdAtMonth; + const MediaFilesData({ + required this.mediaId, + required this.type, + this.uploadState, + this.downloadState, + required this.requiresAuthentication, + required this.stored, + required this.isDraftMedia, + required this.isFavorite, + required this.hasCropAnalyzed, + this.preProgressingProcess, + this.reuploadRequestedBy, + this.displayLimitInMilliseconds, + this.removeAudio, + this.downloadToken, + this.encryptionKey, + this.encryptionMac, + this.encryptionNonce, + this.storedFileHash, + required this.hasThumbnail, + this.sizeInBytes, + required this.createdAt, + this.createdAtMonth, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['media_id'] = Variable(mediaId); + map['type'] = Variable(type); + if (!nullToAbsent || uploadState != null) { + map['upload_state'] = Variable(uploadState); + } + if (!nullToAbsent || downloadState != null) { + map['download_state'] = Variable(downloadState); + } + map['requires_authentication'] = Variable(requiresAuthentication); + map['stored'] = Variable(stored); + map['is_draft_media'] = Variable(isDraftMedia); + map['is_favorite'] = Variable(isFavorite); + map['has_crop_analyzed'] = Variable(hasCropAnalyzed); + if (!nullToAbsent || preProgressingProcess != null) { + map['pre_progressing_process'] = Variable(preProgressingProcess); + } + if (!nullToAbsent || reuploadRequestedBy != null) { + map['reupload_requested_by'] = Variable(reuploadRequestedBy); + } + if (!nullToAbsent || displayLimitInMilliseconds != null) { + map['display_limit_in_milliseconds'] = Variable( + displayLimitInMilliseconds, + ); + } + if (!nullToAbsent || removeAudio != null) { + map['remove_audio'] = Variable(removeAudio); + } + if (!nullToAbsent || downloadToken != null) { + map['download_token'] = Variable(downloadToken); + } + if (!nullToAbsent || encryptionKey != null) { + map['encryption_key'] = Variable(encryptionKey); + } + if (!nullToAbsent || encryptionMac != null) { + map['encryption_mac'] = Variable(encryptionMac); + } + if (!nullToAbsent || encryptionNonce != null) { + map['encryption_nonce'] = Variable(encryptionNonce); + } + if (!nullToAbsent || storedFileHash != null) { + map['stored_file_hash'] = Variable(storedFileHash); + } + map['has_thumbnail'] = Variable(hasThumbnail); + if (!nullToAbsent || sizeInBytes != null) { + map['size_in_bytes'] = Variable(sizeInBytes); + } + map['created_at'] = Variable(createdAt); + if (!nullToAbsent || createdAtMonth != null) { + map['created_at_month'] = Variable(createdAtMonth); + } + return map; + } + + MediaFilesCompanion toCompanion(bool nullToAbsent) { + return MediaFilesCompanion( + mediaId: Value(mediaId), + type: Value(type), + uploadState: uploadState == null && nullToAbsent + ? const Value.absent() + : Value(uploadState), + downloadState: downloadState == null && nullToAbsent + ? const Value.absent() + : Value(downloadState), + requiresAuthentication: Value(requiresAuthentication), + stored: Value(stored), + isDraftMedia: Value(isDraftMedia), + isFavorite: Value(isFavorite), + hasCropAnalyzed: Value(hasCropAnalyzed), + preProgressingProcess: preProgressingProcess == null && nullToAbsent + ? const Value.absent() + : Value(preProgressingProcess), + reuploadRequestedBy: reuploadRequestedBy == null && nullToAbsent + ? const Value.absent() + : Value(reuploadRequestedBy), + displayLimitInMilliseconds: + displayLimitInMilliseconds == null && nullToAbsent + ? const Value.absent() + : Value(displayLimitInMilliseconds), + removeAudio: removeAudio == null && nullToAbsent + ? const Value.absent() + : Value(removeAudio), + downloadToken: downloadToken == null && nullToAbsent + ? const Value.absent() + : Value(downloadToken), + encryptionKey: encryptionKey == null && nullToAbsent + ? const Value.absent() + : Value(encryptionKey), + encryptionMac: encryptionMac == null && nullToAbsent + ? const Value.absent() + : Value(encryptionMac), + encryptionNonce: encryptionNonce == null && nullToAbsent + ? const Value.absent() + : Value(encryptionNonce), + storedFileHash: storedFileHash == null && nullToAbsent + ? const Value.absent() + : Value(storedFileHash), + hasThumbnail: Value(hasThumbnail), + sizeInBytes: sizeInBytes == null && nullToAbsent + ? const Value.absent() + : Value(sizeInBytes), + createdAt: Value(createdAt), + createdAtMonth: createdAtMonth == null && nullToAbsent + ? const Value.absent() + : Value(createdAtMonth), + ); + } + + factory MediaFilesData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return MediaFilesData( + mediaId: serializer.fromJson(json['mediaId']), + type: serializer.fromJson(json['type']), + uploadState: serializer.fromJson(json['uploadState']), + downloadState: serializer.fromJson(json['downloadState']), + requiresAuthentication: serializer.fromJson( + json['requiresAuthentication'], + ), + stored: serializer.fromJson(json['stored']), + isDraftMedia: serializer.fromJson(json['isDraftMedia']), + isFavorite: serializer.fromJson(json['isFavorite']), + hasCropAnalyzed: serializer.fromJson(json['hasCropAnalyzed']), + preProgressingProcess: serializer.fromJson( + json['preProgressingProcess'], + ), + reuploadRequestedBy: serializer.fromJson( + json['reuploadRequestedBy'], + ), + displayLimitInMilliseconds: serializer.fromJson( + json['displayLimitInMilliseconds'], + ), + removeAudio: serializer.fromJson(json['removeAudio']), + downloadToken: serializer.fromJson(json['downloadToken']), + encryptionKey: serializer.fromJson(json['encryptionKey']), + encryptionMac: serializer.fromJson(json['encryptionMac']), + encryptionNonce: serializer.fromJson( + json['encryptionNonce'], + ), + storedFileHash: serializer.fromJson( + json['storedFileHash'], + ), + hasThumbnail: serializer.fromJson(json['hasThumbnail']), + sizeInBytes: serializer.fromJson(json['sizeInBytes']), + createdAt: serializer.fromJson(json['createdAt']), + createdAtMonth: serializer.fromJson(json['createdAtMonth']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'mediaId': serializer.toJson(mediaId), + 'type': serializer.toJson(type), + 'uploadState': serializer.toJson(uploadState), + 'downloadState': serializer.toJson(downloadState), + 'requiresAuthentication': serializer.toJson(requiresAuthentication), + 'stored': serializer.toJson(stored), + 'isDraftMedia': serializer.toJson(isDraftMedia), + 'isFavorite': serializer.toJson(isFavorite), + 'hasCropAnalyzed': serializer.toJson(hasCropAnalyzed), + 'preProgressingProcess': serializer.toJson(preProgressingProcess), + 'reuploadRequestedBy': serializer.toJson(reuploadRequestedBy), + 'displayLimitInMilliseconds': serializer.toJson( + displayLimitInMilliseconds, + ), + 'removeAudio': serializer.toJson(removeAudio), + 'downloadToken': serializer.toJson(downloadToken), + 'encryptionKey': serializer.toJson(encryptionKey), + 'encryptionMac': serializer.toJson(encryptionMac), + 'encryptionNonce': serializer.toJson(encryptionNonce), + 'storedFileHash': serializer.toJson(storedFileHash), + 'hasThumbnail': serializer.toJson(hasThumbnail), + 'sizeInBytes': serializer.toJson(sizeInBytes), + 'createdAt': serializer.toJson(createdAt), + 'createdAtMonth': serializer.toJson(createdAtMonth), + }; + } + + MediaFilesData copyWith({ + String? mediaId, + String? type, + Value uploadState = const Value.absent(), + Value downloadState = const Value.absent(), + int? requiresAuthentication, + int? stored, + int? isDraftMedia, + int? isFavorite, + int? hasCropAnalyzed, + Value preProgressingProcess = const Value.absent(), + Value reuploadRequestedBy = const Value.absent(), + Value displayLimitInMilliseconds = const Value.absent(), + Value removeAudio = const Value.absent(), + Value downloadToken = const Value.absent(), + Value encryptionKey = const Value.absent(), + Value encryptionMac = const Value.absent(), + Value encryptionNonce = const Value.absent(), + Value storedFileHash = const Value.absent(), + int? hasThumbnail, + Value sizeInBytes = const Value.absent(), + int? createdAt, + Value createdAtMonth = const Value.absent(), + }) => MediaFilesData( + mediaId: mediaId ?? this.mediaId, + type: type ?? this.type, + uploadState: uploadState.present ? uploadState.value : this.uploadState, + downloadState: downloadState.present + ? downloadState.value + : this.downloadState, + requiresAuthentication: + requiresAuthentication ?? this.requiresAuthentication, + stored: stored ?? this.stored, + isDraftMedia: isDraftMedia ?? this.isDraftMedia, + isFavorite: isFavorite ?? this.isFavorite, + hasCropAnalyzed: hasCropAnalyzed ?? this.hasCropAnalyzed, + preProgressingProcess: preProgressingProcess.present + ? preProgressingProcess.value + : this.preProgressingProcess, + reuploadRequestedBy: reuploadRequestedBy.present + ? reuploadRequestedBy.value + : this.reuploadRequestedBy, + displayLimitInMilliseconds: displayLimitInMilliseconds.present + ? displayLimitInMilliseconds.value + : this.displayLimitInMilliseconds, + removeAudio: removeAudio.present ? removeAudio.value : this.removeAudio, + downloadToken: downloadToken.present + ? downloadToken.value + : this.downloadToken, + encryptionKey: encryptionKey.present + ? encryptionKey.value + : this.encryptionKey, + encryptionMac: encryptionMac.present + ? encryptionMac.value + : this.encryptionMac, + encryptionNonce: encryptionNonce.present + ? encryptionNonce.value + : this.encryptionNonce, + storedFileHash: storedFileHash.present + ? storedFileHash.value + : this.storedFileHash, + hasThumbnail: hasThumbnail ?? this.hasThumbnail, + sizeInBytes: sizeInBytes.present ? sizeInBytes.value : this.sizeInBytes, + createdAt: createdAt ?? this.createdAt, + createdAtMonth: createdAtMonth.present + ? createdAtMonth.value + : this.createdAtMonth, + ); + MediaFilesData copyWithCompanion(MediaFilesCompanion data) { + return MediaFilesData( + mediaId: data.mediaId.present ? data.mediaId.value : this.mediaId, + type: data.type.present ? data.type.value : this.type, + uploadState: data.uploadState.present + ? data.uploadState.value + : this.uploadState, + downloadState: data.downloadState.present + ? data.downloadState.value + : this.downloadState, + requiresAuthentication: data.requiresAuthentication.present + ? data.requiresAuthentication.value + : this.requiresAuthentication, + stored: data.stored.present ? data.stored.value : this.stored, + isDraftMedia: data.isDraftMedia.present + ? data.isDraftMedia.value + : this.isDraftMedia, + isFavorite: data.isFavorite.present + ? data.isFavorite.value + : this.isFavorite, + hasCropAnalyzed: data.hasCropAnalyzed.present + ? data.hasCropAnalyzed.value + : this.hasCropAnalyzed, + preProgressingProcess: data.preProgressingProcess.present + ? data.preProgressingProcess.value + : this.preProgressingProcess, + reuploadRequestedBy: data.reuploadRequestedBy.present + ? data.reuploadRequestedBy.value + : this.reuploadRequestedBy, + displayLimitInMilliseconds: data.displayLimitInMilliseconds.present + ? data.displayLimitInMilliseconds.value + : this.displayLimitInMilliseconds, + removeAudio: data.removeAudio.present + ? data.removeAudio.value + : this.removeAudio, + downloadToken: data.downloadToken.present + ? data.downloadToken.value + : this.downloadToken, + encryptionKey: data.encryptionKey.present + ? data.encryptionKey.value + : this.encryptionKey, + encryptionMac: data.encryptionMac.present + ? data.encryptionMac.value + : this.encryptionMac, + encryptionNonce: data.encryptionNonce.present + ? data.encryptionNonce.value + : this.encryptionNonce, + storedFileHash: data.storedFileHash.present + ? data.storedFileHash.value + : this.storedFileHash, + hasThumbnail: data.hasThumbnail.present + ? data.hasThumbnail.value + : this.hasThumbnail, + sizeInBytes: data.sizeInBytes.present + ? data.sizeInBytes.value + : this.sizeInBytes, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + createdAtMonth: data.createdAtMonth.present + ? data.createdAtMonth.value + : this.createdAtMonth, + ); + } + + @override + String toString() { + return (StringBuffer('MediaFilesData(') + ..write('mediaId: $mediaId, ') + ..write('type: $type, ') + ..write('uploadState: $uploadState, ') + ..write('downloadState: $downloadState, ') + ..write('requiresAuthentication: $requiresAuthentication, ') + ..write('stored: $stored, ') + ..write('isDraftMedia: $isDraftMedia, ') + ..write('isFavorite: $isFavorite, ') + ..write('hasCropAnalyzed: $hasCropAnalyzed, ') + ..write('preProgressingProcess: $preProgressingProcess, ') + ..write('reuploadRequestedBy: $reuploadRequestedBy, ') + ..write('displayLimitInMilliseconds: $displayLimitInMilliseconds, ') + ..write('removeAudio: $removeAudio, ') + ..write('downloadToken: $downloadToken, ') + ..write('encryptionKey: $encryptionKey, ') + ..write('encryptionMac: $encryptionMac, ') + ..write('encryptionNonce: $encryptionNonce, ') + ..write('storedFileHash: $storedFileHash, ') + ..write('hasThumbnail: $hasThumbnail, ') + ..write('sizeInBytes: $sizeInBytes, ') + ..write('createdAt: $createdAt, ') + ..write('createdAtMonth: $createdAtMonth') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hashAll([ + mediaId, + type, + uploadState, + downloadState, + requiresAuthentication, + stored, + isDraftMedia, + isFavorite, + hasCropAnalyzed, + preProgressingProcess, + reuploadRequestedBy, + displayLimitInMilliseconds, + removeAudio, + $driftBlobEquality.hash(downloadToken), + $driftBlobEquality.hash(encryptionKey), + $driftBlobEquality.hash(encryptionMac), + $driftBlobEquality.hash(encryptionNonce), + $driftBlobEquality.hash(storedFileHash), + hasThumbnail, + sizeInBytes, + createdAt, + createdAtMonth, + ]); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is MediaFilesData && + other.mediaId == this.mediaId && + other.type == this.type && + other.uploadState == this.uploadState && + other.downloadState == this.downloadState && + other.requiresAuthentication == this.requiresAuthentication && + other.stored == this.stored && + other.isDraftMedia == this.isDraftMedia && + other.isFavorite == this.isFavorite && + other.hasCropAnalyzed == this.hasCropAnalyzed && + other.preProgressingProcess == this.preProgressingProcess && + other.reuploadRequestedBy == this.reuploadRequestedBy && + other.displayLimitInMilliseconds == this.displayLimitInMilliseconds && + other.removeAudio == this.removeAudio && + $driftBlobEquality.equals(other.downloadToken, this.downloadToken) && + $driftBlobEquality.equals(other.encryptionKey, this.encryptionKey) && + $driftBlobEquality.equals(other.encryptionMac, this.encryptionMac) && + $driftBlobEquality.equals( + other.encryptionNonce, + this.encryptionNonce, + ) && + $driftBlobEquality.equals( + other.storedFileHash, + this.storedFileHash, + ) && + other.hasThumbnail == this.hasThumbnail && + other.sizeInBytes == this.sizeInBytes && + other.createdAt == this.createdAt && + other.createdAtMonth == this.createdAtMonth); +} + +class MediaFilesCompanion extends UpdateCompanion { + final Value mediaId; + final Value type; + final Value uploadState; + final Value downloadState; + final Value requiresAuthentication; + final Value stored; + final Value isDraftMedia; + final Value isFavorite; + final Value hasCropAnalyzed; + final Value preProgressingProcess; + final Value reuploadRequestedBy; + final Value displayLimitInMilliseconds; + final Value removeAudio; + final Value downloadToken; + final Value encryptionKey; + final Value encryptionMac; + final Value encryptionNonce; + final Value storedFileHash; + final Value hasThumbnail; + final Value sizeInBytes; + final Value createdAt; + final Value createdAtMonth; + final Value rowid; + const MediaFilesCompanion({ + this.mediaId = const Value.absent(), + this.type = const Value.absent(), + this.uploadState = const Value.absent(), + this.downloadState = const Value.absent(), + this.requiresAuthentication = const Value.absent(), + this.stored = const Value.absent(), + this.isDraftMedia = const Value.absent(), + this.isFavorite = const Value.absent(), + this.hasCropAnalyzed = const Value.absent(), + this.preProgressingProcess = const Value.absent(), + this.reuploadRequestedBy = const Value.absent(), + this.displayLimitInMilliseconds = const Value.absent(), + this.removeAudio = const Value.absent(), + this.downloadToken = const Value.absent(), + this.encryptionKey = const Value.absent(), + this.encryptionMac = const Value.absent(), + this.encryptionNonce = const Value.absent(), + this.storedFileHash = const Value.absent(), + this.hasThumbnail = const Value.absent(), + this.sizeInBytes = const Value.absent(), + this.createdAt = const Value.absent(), + this.createdAtMonth = const Value.absent(), + this.rowid = const Value.absent(), + }); + MediaFilesCompanion.insert({ + required String mediaId, + required String type, + this.uploadState = const Value.absent(), + this.downloadState = const Value.absent(), + this.requiresAuthentication = const Value.absent(), + this.stored = const Value.absent(), + this.isDraftMedia = const Value.absent(), + this.isFavorite = const Value.absent(), + this.hasCropAnalyzed = const Value.absent(), + this.preProgressingProcess = const Value.absent(), + this.reuploadRequestedBy = const Value.absent(), + this.displayLimitInMilliseconds = const Value.absent(), + this.removeAudio = const Value.absent(), + this.downloadToken = const Value.absent(), + this.encryptionKey = const Value.absent(), + this.encryptionMac = const Value.absent(), + this.encryptionNonce = const Value.absent(), + this.storedFileHash = const Value.absent(), + this.hasThumbnail = const Value.absent(), + this.sizeInBytes = const Value.absent(), + this.createdAt = const Value.absent(), + this.createdAtMonth = const Value.absent(), + this.rowid = const Value.absent(), + }) : mediaId = Value(mediaId), + type = Value(type); + static Insertable custom({ + Expression? mediaId, + Expression? type, + Expression? uploadState, + Expression? downloadState, + Expression? requiresAuthentication, + Expression? stored, + Expression? isDraftMedia, + Expression? isFavorite, + Expression? hasCropAnalyzed, + Expression? preProgressingProcess, + Expression? reuploadRequestedBy, + Expression? displayLimitInMilliseconds, + Expression? removeAudio, + Expression? downloadToken, + Expression? encryptionKey, + Expression? encryptionMac, + Expression? encryptionNonce, + Expression? storedFileHash, + Expression? hasThumbnail, + Expression? sizeInBytes, + Expression? createdAt, + Expression? createdAtMonth, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (mediaId != null) 'media_id': mediaId, + if (type != null) 'type': type, + if (uploadState != null) 'upload_state': uploadState, + if (downloadState != null) 'download_state': downloadState, + if (requiresAuthentication != null) + 'requires_authentication': requiresAuthentication, + if (stored != null) 'stored': stored, + if (isDraftMedia != null) 'is_draft_media': isDraftMedia, + if (isFavorite != null) 'is_favorite': isFavorite, + if (hasCropAnalyzed != null) 'has_crop_analyzed': hasCropAnalyzed, + if (preProgressingProcess != null) + 'pre_progressing_process': preProgressingProcess, + if (reuploadRequestedBy != null) + 'reupload_requested_by': reuploadRequestedBy, + if (displayLimitInMilliseconds != null) + 'display_limit_in_milliseconds': displayLimitInMilliseconds, + if (removeAudio != null) 'remove_audio': removeAudio, + if (downloadToken != null) 'download_token': downloadToken, + if (encryptionKey != null) 'encryption_key': encryptionKey, + if (encryptionMac != null) 'encryption_mac': encryptionMac, + if (encryptionNonce != null) 'encryption_nonce': encryptionNonce, + if (storedFileHash != null) 'stored_file_hash': storedFileHash, + if (hasThumbnail != null) 'has_thumbnail': hasThumbnail, + if (sizeInBytes != null) 'size_in_bytes': sizeInBytes, + if (createdAt != null) 'created_at': createdAt, + if (createdAtMonth != null) 'created_at_month': createdAtMonth, + if (rowid != null) 'rowid': rowid, + }); + } + + MediaFilesCompanion copyWith({ + Value? mediaId, + Value? type, + Value? uploadState, + Value? downloadState, + Value? requiresAuthentication, + Value? stored, + Value? isDraftMedia, + Value? isFavorite, + Value? hasCropAnalyzed, + Value? preProgressingProcess, + Value? reuploadRequestedBy, + Value? displayLimitInMilliseconds, + Value? removeAudio, + Value? downloadToken, + Value? encryptionKey, + Value? encryptionMac, + Value? encryptionNonce, + Value? storedFileHash, + Value? hasThumbnail, + Value? sizeInBytes, + Value? createdAt, + Value? createdAtMonth, + Value? rowid, + }) { + return MediaFilesCompanion( + mediaId: mediaId ?? this.mediaId, + type: type ?? this.type, + uploadState: uploadState ?? this.uploadState, + downloadState: downloadState ?? this.downloadState, + requiresAuthentication: + requiresAuthentication ?? this.requiresAuthentication, + stored: stored ?? this.stored, + isDraftMedia: isDraftMedia ?? this.isDraftMedia, + isFavorite: isFavorite ?? this.isFavorite, + hasCropAnalyzed: hasCropAnalyzed ?? this.hasCropAnalyzed, + preProgressingProcess: + preProgressingProcess ?? this.preProgressingProcess, + reuploadRequestedBy: reuploadRequestedBy ?? this.reuploadRequestedBy, + displayLimitInMilliseconds: + displayLimitInMilliseconds ?? this.displayLimitInMilliseconds, + removeAudio: removeAudio ?? this.removeAudio, + downloadToken: downloadToken ?? this.downloadToken, + encryptionKey: encryptionKey ?? this.encryptionKey, + encryptionMac: encryptionMac ?? this.encryptionMac, + encryptionNonce: encryptionNonce ?? this.encryptionNonce, + storedFileHash: storedFileHash ?? this.storedFileHash, + hasThumbnail: hasThumbnail ?? this.hasThumbnail, + sizeInBytes: sizeInBytes ?? this.sizeInBytes, + createdAt: createdAt ?? this.createdAt, + createdAtMonth: createdAtMonth ?? this.createdAtMonth, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (mediaId.present) { + map['media_id'] = Variable(mediaId.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (uploadState.present) { + map['upload_state'] = Variable(uploadState.value); + } + if (downloadState.present) { + map['download_state'] = Variable(downloadState.value); + } + if (requiresAuthentication.present) { + map['requires_authentication'] = Variable( + requiresAuthentication.value, + ); + } + if (stored.present) { + map['stored'] = Variable(stored.value); + } + if (isDraftMedia.present) { + map['is_draft_media'] = Variable(isDraftMedia.value); + } + if (isFavorite.present) { + map['is_favorite'] = Variable(isFavorite.value); + } + if (hasCropAnalyzed.present) { + map['has_crop_analyzed'] = Variable(hasCropAnalyzed.value); + } + if (preProgressingProcess.present) { + map['pre_progressing_process'] = Variable( + preProgressingProcess.value, + ); + } + if (reuploadRequestedBy.present) { + map['reupload_requested_by'] = Variable( + reuploadRequestedBy.value, + ); + } + if (displayLimitInMilliseconds.present) { + map['display_limit_in_milliseconds'] = Variable( + displayLimitInMilliseconds.value, + ); + } + if (removeAudio.present) { + map['remove_audio'] = Variable(removeAudio.value); + } + if (downloadToken.present) { + map['download_token'] = Variable(downloadToken.value); + } + if (encryptionKey.present) { + map['encryption_key'] = Variable(encryptionKey.value); + } + if (encryptionMac.present) { + map['encryption_mac'] = Variable(encryptionMac.value); + } + if (encryptionNonce.present) { + map['encryption_nonce'] = Variable(encryptionNonce.value); + } + if (storedFileHash.present) { + map['stored_file_hash'] = Variable(storedFileHash.value); + } + if (hasThumbnail.present) { + map['has_thumbnail'] = Variable(hasThumbnail.value); + } + if (sizeInBytes.present) { + map['size_in_bytes'] = Variable(sizeInBytes.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (createdAtMonth.present) { + map['created_at_month'] = Variable(createdAtMonth.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('MediaFilesCompanion(') + ..write('mediaId: $mediaId, ') + ..write('type: $type, ') + ..write('uploadState: $uploadState, ') + ..write('downloadState: $downloadState, ') + ..write('requiresAuthentication: $requiresAuthentication, ') + ..write('stored: $stored, ') + ..write('isDraftMedia: $isDraftMedia, ') + ..write('isFavorite: $isFavorite, ') + ..write('hasCropAnalyzed: $hasCropAnalyzed, ') + ..write('preProgressingProcess: $preProgressingProcess, ') + ..write('reuploadRequestedBy: $reuploadRequestedBy, ') + ..write('displayLimitInMilliseconds: $displayLimitInMilliseconds, ') + ..write('removeAudio: $removeAudio, ') + ..write('downloadToken: $downloadToken, ') + ..write('encryptionKey: $encryptionKey, ') + ..write('encryptionMac: $encryptionMac, ') + ..write('encryptionNonce: $encryptionNonce, ') + ..write('storedFileHash: $storedFileHash, ') + ..write('hasThumbnail: $hasThumbnail, ') + ..write('sizeInBytes: $sizeInBytes, ') + ..write('createdAt: $createdAt, ') + ..write('createdAtMonth: $createdAtMonth, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class Messages extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + Messages(this.attachedDatabase, [this._alias]); + late final GeneratedColumn groupId = GeneratedColumn( + 'group_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES "groups"(group_id)ON DELETE CASCADE', + ); + late final GeneratedColumn messageId = GeneratedColumn( + 'message_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn senderId = GeneratedColumn( + 'sender_id', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL REFERENCES contacts(user_id)', + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn content = GeneratedColumn( + 'content', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn mediaId = GeneratedColumn( + 'media_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: + 'NULL REFERENCES media_files(media_id)ON DELETE SET NULL', + ); + late final GeneratedColumn additionalMessageData = + GeneratedColumn( + 'additional_message_data', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn mediaStored = GeneratedColumn( + 'media_stored', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (media_stored IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn mediaReopened = GeneratedColumn( + 'media_reopened', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (media_reopened IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn downloadToken = + GeneratedColumn( + 'download_token', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn quotesMessageId = GeneratedColumn( + 'quotes_message_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn isDeletedFromSender = GeneratedColumn( + 'is_deleted_from_sender', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 CHECK (is_deleted_from_sender IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn openedAt = GeneratedColumn( + 'opened_at', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn openedByAll = GeneratedColumn( + 'opened_by_all', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + late final GeneratedColumn modifiedAt = GeneratedColumn( + 'modified_at', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn ackByUser = GeneratedColumn( + 'ack_by_user', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn ackByServer = GeneratedColumn( + 'ack_by_server', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + @override + List get $columns => [ + groupId, + messageId, + senderId, + type, + content, + mediaId, + additionalMessageData, + mediaStored, + mediaReopened, + downloadToken, + quotesMessageId, + isDeletedFromSender, + openedAt, + openedByAll, + createdAt, + modifiedAt, + ackByUser, + ackByServer, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'messages'; + @override + Set get $primaryKey => {messageId}; + @override + MessagesData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return MessagesData( + groupId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}group_id'], + )!, + messageId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}message_id'], + )!, + senderId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}sender_id'], + ), + type: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}type'], + )!, + content: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}content'], + ), + mediaId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}media_id'], + ), + additionalMessageData: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}additional_message_data'], + ), + mediaStored: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}media_stored'], + )!, + mediaReopened: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}media_reopened'], + )!, + downloadToken: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}download_token'], + ), + quotesMessageId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}quotes_message_id'], + ), + isDeletedFromSender: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_deleted_from_sender'], + )!, + openedAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}opened_at'], + ), + openedByAll: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}opened_by_all'], + ), + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + modifiedAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}modified_at'], + ), + ackByUser: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}ack_by_user'], + ), + ackByServer: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}ack_by_server'], + ), + ); + } + + @override + Messages createAlias(String alias) { + return Messages(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(message_id)']; + @override + bool get dontWriteConstraints => true; +} + +class MessagesData extends DataClass implements Insertable { + final String groupId; + final String messageId; + final int? senderId; + final String type; + final String? content; + final String? mediaId; + final i2.Uint8List? additionalMessageData; + final int mediaStored; + final int mediaReopened; + final i2.Uint8List? downloadToken; + final String? quotesMessageId; + final int isDeletedFromSender; + final int? openedAt; + final int? openedByAll; + final int createdAt; + final int? modifiedAt; + final int? ackByUser; + final int? ackByServer; + const MessagesData({ + required this.groupId, + required this.messageId, + this.senderId, + required this.type, + this.content, + this.mediaId, + this.additionalMessageData, + required this.mediaStored, + required this.mediaReopened, + this.downloadToken, + this.quotesMessageId, + required this.isDeletedFromSender, + this.openedAt, + this.openedByAll, + required this.createdAt, + this.modifiedAt, + this.ackByUser, + this.ackByServer, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['group_id'] = Variable(groupId); + map['message_id'] = Variable(messageId); + if (!nullToAbsent || senderId != null) { + map['sender_id'] = Variable(senderId); + } + map['type'] = Variable(type); + if (!nullToAbsent || content != null) { + map['content'] = Variable(content); + } + if (!nullToAbsent || mediaId != null) { + map['media_id'] = Variable(mediaId); + } + if (!nullToAbsent || additionalMessageData != null) { + map['additional_message_data'] = Variable( + additionalMessageData, + ); + } + map['media_stored'] = Variable(mediaStored); + map['media_reopened'] = Variable(mediaReopened); + if (!nullToAbsent || downloadToken != null) { + map['download_token'] = Variable(downloadToken); + } + if (!nullToAbsent || quotesMessageId != null) { + map['quotes_message_id'] = Variable(quotesMessageId); + } + map['is_deleted_from_sender'] = Variable(isDeletedFromSender); + if (!nullToAbsent || openedAt != null) { + map['opened_at'] = Variable(openedAt); + } + if (!nullToAbsent || openedByAll != null) { + map['opened_by_all'] = Variable(openedByAll); + } + map['created_at'] = Variable(createdAt); + if (!nullToAbsent || modifiedAt != null) { + map['modified_at'] = Variable(modifiedAt); + } + if (!nullToAbsent || ackByUser != null) { + map['ack_by_user'] = Variable(ackByUser); + } + if (!nullToAbsent || ackByServer != null) { + map['ack_by_server'] = Variable(ackByServer); + } + return map; + } + + MessagesCompanion toCompanion(bool nullToAbsent) { + return MessagesCompanion( + groupId: Value(groupId), + messageId: Value(messageId), + senderId: senderId == null && nullToAbsent + ? const Value.absent() + : Value(senderId), + type: Value(type), + content: content == null && nullToAbsent + ? const Value.absent() + : Value(content), + mediaId: mediaId == null && nullToAbsent + ? const Value.absent() + : Value(mediaId), + additionalMessageData: additionalMessageData == null && nullToAbsent + ? const Value.absent() + : Value(additionalMessageData), + mediaStored: Value(mediaStored), + mediaReopened: Value(mediaReopened), + downloadToken: downloadToken == null && nullToAbsent + ? const Value.absent() + : Value(downloadToken), + quotesMessageId: quotesMessageId == null && nullToAbsent + ? const Value.absent() + : Value(quotesMessageId), + isDeletedFromSender: Value(isDeletedFromSender), + openedAt: openedAt == null && nullToAbsent + ? const Value.absent() + : Value(openedAt), + openedByAll: openedByAll == null && nullToAbsent + ? const Value.absent() + : Value(openedByAll), + createdAt: Value(createdAt), + modifiedAt: modifiedAt == null && nullToAbsent + ? const Value.absent() + : Value(modifiedAt), + ackByUser: ackByUser == null && nullToAbsent + ? const Value.absent() + : Value(ackByUser), + ackByServer: ackByServer == null && nullToAbsent + ? const Value.absent() + : Value(ackByServer), + ); + } + + factory MessagesData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return MessagesData( + groupId: serializer.fromJson(json['groupId']), + messageId: serializer.fromJson(json['messageId']), + senderId: serializer.fromJson(json['senderId']), + type: serializer.fromJson(json['type']), + content: serializer.fromJson(json['content']), + mediaId: serializer.fromJson(json['mediaId']), + additionalMessageData: serializer.fromJson( + json['additionalMessageData'], + ), + mediaStored: serializer.fromJson(json['mediaStored']), + mediaReopened: serializer.fromJson(json['mediaReopened']), + downloadToken: serializer.fromJson(json['downloadToken']), + quotesMessageId: serializer.fromJson(json['quotesMessageId']), + isDeletedFromSender: serializer.fromJson( + json['isDeletedFromSender'], + ), + openedAt: serializer.fromJson(json['openedAt']), + openedByAll: serializer.fromJson(json['openedByAll']), + createdAt: serializer.fromJson(json['createdAt']), + modifiedAt: serializer.fromJson(json['modifiedAt']), + ackByUser: serializer.fromJson(json['ackByUser']), + ackByServer: serializer.fromJson(json['ackByServer']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'groupId': serializer.toJson(groupId), + 'messageId': serializer.toJson(messageId), + 'senderId': serializer.toJson(senderId), + 'type': serializer.toJson(type), + 'content': serializer.toJson(content), + 'mediaId': serializer.toJson(mediaId), + 'additionalMessageData': serializer.toJson( + additionalMessageData, + ), + 'mediaStored': serializer.toJson(mediaStored), + 'mediaReopened': serializer.toJson(mediaReopened), + 'downloadToken': serializer.toJson(downloadToken), + 'quotesMessageId': serializer.toJson(quotesMessageId), + 'isDeletedFromSender': serializer.toJson(isDeletedFromSender), + 'openedAt': serializer.toJson(openedAt), + 'openedByAll': serializer.toJson(openedByAll), + 'createdAt': serializer.toJson(createdAt), + 'modifiedAt': serializer.toJson(modifiedAt), + 'ackByUser': serializer.toJson(ackByUser), + 'ackByServer': serializer.toJson(ackByServer), + }; + } + + MessagesData copyWith({ + String? groupId, + String? messageId, + Value senderId = const Value.absent(), + String? type, + Value content = const Value.absent(), + Value mediaId = const Value.absent(), + Value additionalMessageData = const Value.absent(), + int? mediaStored, + int? mediaReopened, + Value downloadToken = const Value.absent(), + Value quotesMessageId = const Value.absent(), + int? isDeletedFromSender, + Value openedAt = const Value.absent(), + Value openedByAll = const Value.absent(), + int? createdAt, + Value modifiedAt = const Value.absent(), + Value ackByUser = const Value.absent(), + Value ackByServer = const Value.absent(), + }) => MessagesData( + groupId: groupId ?? this.groupId, + messageId: messageId ?? this.messageId, + senderId: senderId.present ? senderId.value : this.senderId, + type: type ?? this.type, + content: content.present ? content.value : this.content, + mediaId: mediaId.present ? mediaId.value : this.mediaId, + additionalMessageData: additionalMessageData.present + ? additionalMessageData.value + : this.additionalMessageData, + mediaStored: mediaStored ?? this.mediaStored, + mediaReopened: mediaReopened ?? this.mediaReopened, + downloadToken: downloadToken.present + ? downloadToken.value + : this.downloadToken, + quotesMessageId: quotesMessageId.present + ? quotesMessageId.value + : this.quotesMessageId, + isDeletedFromSender: isDeletedFromSender ?? this.isDeletedFromSender, + openedAt: openedAt.present ? openedAt.value : this.openedAt, + openedByAll: openedByAll.present ? openedByAll.value : this.openedByAll, + createdAt: createdAt ?? this.createdAt, + modifiedAt: modifiedAt.present ? modifiedAt.value : this.modifiedAt, + ackByUser: ackByUser.present ? ackByUser.value : this.ackByUser, + ackByServer: ackByServer.present ? ackByServer.value : this.ackByServer, + ); + MessagesData copyWithCompanion(MessagesCompanion data) { + return MessagesData( + groupId: data.groupId.present ? data.groupId.value : this.groupId, + messageId: data.messageId.present ? data.messageId.value : this.messageId, + senderId: data.senderId.present ? data.senderId.value : this.senderId, + type: data.type.present ? data.type.value : this.type, + content: data.content.present ? data.content.value : this.content, + mediaId: data.mediaId.present ? data.mediaId.value : this.mediaId, + additionalMessageData: data.additionalMessageData.present + ? data.additionalMessageData.value + : this.additionalMessageData, + mediaStored: data.mediaStored.present + ? data.mediaStored.value + : this.mediaStored, + mediaReopened: data.mediaReopened.present + ? data.mediaReopened.value + : this.mediaReopened, + downloadToken: data.downloadToken.present + ? data.downloadToken.value + : this.downloadToken, + quotesMessageId: data.quotesMessageId.present + ? data.quotesMessageId.value + : this.quotesMessageId, + isDeletedFromSender: data.isDeletedFromSender.present + ? data.isDeletedFromSender.value + : this.isDeletedFromSender, + openedAt: data.openedAt.present ? data.openedAt.value : this.openedAt, + openedByAll: data.openedByAll.present + ? data.openedByAll.value + : this.openedByAll, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + modifiedAt: data.modifiedAt.present + ? data.modifiedAt.value + : this.modifiedAt, + ackByUser: data.ackByUser.present ? data.ackByUser.value : this.ackByUser, + ackByServer: data.ackByServer.present + ? data.ackByServer.value + : this.ackByServer, + ); + } + + @override + String toString() { + return (StringBuffer('MessagesData(') + ..write('groupId: $groupId, ') + ..write('messageId: $messageId, ') + ..write('senderId: $senderId, ') + ..write('type: $type, ') + ..write('content: $content, ') + ..write('mediaId: $mediaId, ') + ..write('additionalMessageData: $additionalMessageData, ') + ..write('mediaStored: $mediaStored, ') + ..write('mediaReopened: $mediaReopened, ') + ..write('downloadToken: $downloadToken, ') + ..write('quotesMessageId: $quotesMessageId, ') + ..write('isDeletedFromSender: $isDeletedFromSender, ') + ..write('openedAt: $openedAt, ') + ..write('openedByAll: $openedByAll, ') + ..write('createdAt: $createdAt, ') + ..write('modifiedAt: $modifiedAt, ') + ..write('ackByUser: $ackByUser, ') + ..write('ackByServer: $ackByServer') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + groupId, + messageId, + senderId, + type, + content, + mediaId, + $driftBlobEquality.hash(additionalMessageData), + mediaStored, + mediaReopened, + $driftBlobEquality.hash(downloadToken), + quotesMessageId, + isDeletedFromSender, + openedAt, + openedByAll, + createdAt, + modifiedAt, + ackByUser, + ackByServer, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is MessagesData && + other.groupId == this.groupId && + other.messageId == this.messageId && + other.senderId == this.senderId && + other.type == this.type && + other.content == this.content && + other.mediaId == this.mediaId && + $driftBlobEquality.equals( + other.additionalMessageData, + this.additionalMessageData, + ) && + other.mediaStored == this.mediaStored && + other.mediaReopened == this.mediaReopened && + $driftBlobEquality.equals(other.downloadToken, this.downloadToken) && + other.quotesMessageId == this.quotesMessageId && + other.isDeletedFromSender == this.isDeletedFromSender && + other.openedAt == this.openedAt && + other.openedByAll == this.openedByAll && + other.createdAt == this.createdAt && + other.modifiedAt == this.modifiedAt && + other.ackByUser == this.ackByUser && + other.ackByServer == this.ackByServer); +} + +class MessagesCompanion extends UpdateCompanion { + final Value groupId; + final Value messageId; + final Value senderId; + final Value type; + final Value content; + final Value mediaId; + final Value additionalMessageData; + final Value mediaStored; + final Value mediaReopened; + final Value downloadToken; + final Value quotesMessageId; + final Value isDeletedFromSender; + final Value openedAt; + final Value openedByAll; + final Value createdAt; + final Value modifiedAt; + final Value ackByUser; + final Value ackByServer; + final Value rowid; + const MessagesCompanion({ + this.groupId = const Value.absent(), + this.messageId = const Value.absent(), + this.senderId = const Value.absent(), + this.type = const Value.absent(), + this.content = const Value.absent(), + this.mediaId = const Value.absent(), + this.additionalMessageData = const Value.absent(), + this.mediaStored = const Value.absent(), + this.mediaReopened = const Value.absent(), + this.downloadToken = const Value.absent(), + this.quotesMessageId = const Value.absent(), + this.isDeletedFromSender = const Value.absent(), + this.openedAt = const Value.absent(), + this.openedByAll = const Value.absent(), + this.createdAt = const Value.absent(), + this.modifiedAt = const Value.absent(), + this.ackByUser = const Value.absent(), + this.ackByServer = const Value.absent(), + this.rowid = const Value.absent(), + }); + MessagesCompanion.insert({ + required String groupId, + required String messageId, + this.senderId = const Value.absent(), + required String type, + this.content = const Value.absent(), + this.mediaId = const Value.absent(), + this.additionalMessageData = const Value.absent(), + this.mediaStored = const Value.absent(), + this.mediaReopened = const Value.absent(), + this.downloadToken = const Value.absent(), + this.quotesMessageId = const Value.absent(), + this.isDeletedFromSender = const Value.absent(), + this.openedAt = const Value.absent(), + this.openedByAll = const Value.absent(), + this.createdAt = const Value.absent(), + this.modifiedAt = const Value.absent(), + this.ackByUser = const Value.absent(), + this.ackByServer = const Value.absent(), + this.rowid = const Value.absent(), + }) : groupId = Value(groupId), + messageId = Value(messageId), + type = Value(type); + static Insertable custom({ + Expression? groupId, + Expression? messageId, + Expression? senderId, + Expression? type, + Expression? content, + Expression? mediaId, + Expression? additionalMessageData, + Expression? mediaStored, + Expression? mediaReopened, + Expression? downloadToken, + Expression? quotesMessageId, + Expression? isDeletedFromSender, + Expression? openedAt, + Expression? openedByAll, + Expression? createdAt, + Expression? modifiedAt, + Expression? ackByUser, + Expression? ackByServer, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (groupId != null) 'group_id': groupId, + if (messageId != null) 'message_id': messageId, + if (senderId != null) 'sender_id': senderId, + if (type != null) 'type': type, + if (content != null) 'content': content, + if (mediaId != null) 'media_id': mediaId, + if (additionalMessageData != null) + 'additional_message_data': additionalMessageData, + if (mediaStored != null) 'media_stored': mediaStored, + if (mediaReopened != null) 'media_reopened': mediaReopened, + if (downloadToken != null) 'download_token': downloadToken, + if (quotesMessageId != null) 'quotes_message_id': quotesMessageId, + if (isDeletedFromSender != null) + 'is_deleted_from_sender': isDeletedFromSender, + if (openedAt != null) 'opened_at': openedAt, + if (openedByAll != null) 'opened_by_all': openedByAll, + if (createdAt != null) 'created_at': createdAt, + if (modifiedAt != null) 'modified_at': modifiedAt, + if (ackByUser != null) 'ack_by_user': ackByUser, + if (ackByServer != null) 'ack_by_server': ackByServer, + if (rowid != null) 'rowid': rowid, + }); + } + + MessagesCompanion copyWith({ + Value? groupId, + Value? messageId, + Value? senderId, + Value? type, + Value? content, + Value? mediaId, + Value? additionalMessageData, + Value? mediaStored, + Value? mediaReopened, + Value? downloadToken, + Value? quotesMessageId, + Value? isDeletedFromSender, + Value? openedAt, + Value? openedByAll, + Value? createdAt, + Value? modifiedAt, + Value? ackByUser, + Value? ackByServer, + Value? rowid, + }) { + return MessagesCompanion( + groupId: groupId ?? this.groupId, + messageId: messageId ?? this.messageId, + senderId: senderId ?? this.senderId, + type: type ?? this.type, + content: content ?? this.content, + mediaId: mediaId ?? this.mediaId, + additionalMessageData: + additionalMessageData ?? this.additionalMessageData, + mediaStored: mediaStored ?? this.mediaStored, + mediaReopened: mediaReopened ?? this.mediaReopened, + downloadToken: downloadToken ?? this.downloadToken, + quotesMessageId: quotesMessageId ?? this.quotesMessageId, + isDeletedFromSender: isDeletedFromSender ?? this.isDeletedFromSender, + openedAt: openedAt ?? this.openedAt, + openedByAll: openedByAll ?? this.openedByAll, + createdAt: createdAt ?? this.createdAt, + modifiedAt: modifiedAt ?? this.modifiedAt, + ackByUser: ackByUser ?? this.ackByUser, + ackByServer: ackByServer ?? this.ackByServer, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (groupId.present) { + map['group_id'] = Variable(groupId.value); + } + if (messageId.present) { + map['message_id'] = Variable(messageId.value); + } + if (senderId.present) { + map['sender_id'] = Variable(senderId.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (content.present) { + map['content'] = Variable(content.value); + } + if (mediaId.present) { + map['media_id'] = Variable(mediaId.value); + } + if (additionalMessageData.present) { + map['additional_message_data'] = Variable( + additionalMessageData.value, + ); + } + if (mediaStored.present) { + map['media_stored'] = Variable(mediaStored.value); + } + if (mediaReopened.present) { + map['media_reopened'] = Variable(mediaReopened.value); + } + if (downloadToken.present) { + map['download_token'] = Variable(downloadToken.value); + } + if (quotesMessageId.present) { + map['quotes_message_id'] = Variable(quotesMessageId.value); + } + if (isDeletedFromSender.present) { + map['is_deleted_from_sender'] = Variable(isDeletedFromSender.value); + } + if (openedAt.present) { + map['opened_at'] = Variable(openedAt.value); + } + if (openedByAll.present) { + map['opened_by_all'] = Variable(openedByAll.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (modifiedAt.present) { + map['modified_at'] = Variable(modifiedAt.value); + } + if (ackByUser.present) { + map['ack_by_user'] = Variable(ackByUser.value); + } + if (ackByServer.present) { + map['ack_by_server'] = Variable(ackByServer.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('MessagesCompanion(') + ..write('groupId: $groupId, ') + ..write('messageId: $messageId, ') + ..write('senderId: $senderId, ') + ..write('type: $type, ') + ..write('content: $content, ') + ..write('mediaId: $mediaId, ') + ..write('additionalMessageData: $additionalMessageData, ') + ..write('mediaStored: $mediaStored, ') + ..write('mediaReopened: $mediaReopened, ') + ..write('downloadToken: $downloadToken, ') + ..write('quotesMessageId: $quotesMessageId, ') + ..write('isDeletedFromSender: $isDeletedFromSender, ') + ..write('openedAt: $openedAt, ') + ..write('openedByAll: $openedByAll, ') + ..write('createdAt: $createdAt, ') + ..write('modifiedAt: $modifiedAt, ') + ..write('ackByUser: $ackByUser, ') + ..write('ackByServer: $ackByServer, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class MessageHistories extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + MessageHistories(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL PRIMARY KEY AUTOINCREMENT', + ); + late final GeneratedColumn messageId = GeneratedColumn( + 'message_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES messages(message_id)ON DELETE CASCADE', + ); + late final GeneratedColumn contactId = GeneratedColumn( + 'contact_id', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL REFERENCES contacts(user_id)ON DELETE CASCADE', + ); + late final GeneratedColumn content = GeneratedColumn( + 'content', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [ + id, + messageId, + contactId, + content, + createdAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'message_histories'; + @override + Set get $primaryKey => {id}; + @override + MessageHistoriesData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return MessageHistoriesData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}id'], + )!, + messageId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}message_id'], + )!, + contactId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}contact_id'], + ), + content: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}content'], + ), + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + MessageHistories createAlias(String alias) { + return MessageHistories(attachedDatabase, alias); + } + + @override + bool get dontWriteConstraints => true; +} + +class MessageHistoriesData extends DataClass + implements Insertable { + final int id; + final String messageId; + final int? contactId; + final String? content; + final int createdAt; + const MessageHistoriesData({ + required this.id, + required this.messageId, + this.contactId, + this.content, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['message_id'] = Variable(messageId); + if (!nullToAbsent || contactId != null) { + map['contact_id'] = Variable(contactId); + } + if (!nullToAbsent || content != null) { + map['content'] = Variable(content); + } + map['created_at'] = Variable(createdAt); + return map; + } + + MessageHistoriesCompanion toCompanion(bool nullToAbsent) { + return MessageHistoriesCompanion( + id: Value(id), + messageId: Value(messageId), + contactId: contactId == null && nullToAbsent + ? const Value.absent() + : Value(contactId), + content: content == null && nullToAbsent + ? const Value.absent() + : Value(content), + createdAt: Value(createdAt), + ); + } + + factory MessageHistoriesData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return MessageHistoriesData( + id: serializer.fromJson(json['id']), + messageId: serializer.fromJson(json['messageId']), + contactId: serializer.fromJson(json['contactId']), + content: serializer.fromJson(json['content']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'messageId': serializer.toJson(messageId), + 'contactId': serializer.toJson(contactId), + 'content': serializer.toJson(content), + 'createdAt': serializer.toJson(createdAt), + }; + } + + MessageHistoriesData copyWith({ + int? id, + String? messageId, + Value contactId = const Value.absent(), + Value content = const Value.absent(), + int? createdAt, + }) => MessageHistoriesData( + id: id ?? this.id, + messageId: messageId ?? this.messageId, + contactId: contactId.present ? contactId.value : this.contactId, + content: content.present ? content.value : this.content, + createdAt: createdAt ?? this.createdAt, + ); + MessageHistoriesData copyWithCompanion(MessageHistoriesCompanion data) { + return MessageHistoriesData( + id: data.id.present ? data.id.value : this.id, + messageId: data.messageId.present ? data.messageId.value : this.messageId, + contactId: data.contactId.present ? data.contactId.value : this.contactId, + content: data.content.present ? data.content.value : this.content, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('MessageHistoriesData(') + ..write('id: $id, ') + ..write('messageId: $messageId, ') + ..write('contactId: $contactId, ') + ..write('content: $content, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, messageId, contactId, content, createdAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is MessageHistoriesData && + other.id == this.id && + other.messageId == this.messageId && + other.contactId == this.contactId && + other.content == this.content && + other.createdAt == this.createdAt); +} + +class MessageHistoriesCompanion extends UpdateCompanion { + final Value id; + final Value messageId; + final Value contactId; + final Value content; + final Value createdAt; + const MessageHistoriesCompanion({ + this.id = const Value.absent(), + this.messageId = const Value.absent(), + this.contactId = const Value.absent(), + this.content = const Value.absent(), + this.createdAt = const Value.absent(), + }); + MessageHistoriesCompanion.insert({ + this.id = const Value.absent(), + required String messageId, + this.contactId = const Value.absent(), + this.content = const Value.absent(), + this.createdAt = const Value.absent(), + }) : messageId = Value(messageId); + static Insertable custom({ + Expression? id, + Expression? messageId, + Expression? contactId, + Expression? content, + Expression? createdAt, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (messageId != null) 'message_id': messageId, + if (contactId != null) 'contact_id': contactId, + if (content != null) 'content': content, + if (createdAt != null) 'created_at': createdAt, + }); + } + + MessageHistoriesCompanion copyWith({ + Value? id, + Value? messageId, + Value? contactId, + Value? content, + Value? createdAt, + }) { + return MessageHistoriesCompanion( + id: id ?? this.id, + messageId: messageId ?? this.messageId, + contactId: contactId ?? this.contactId, + content: content ?? this.content, + createdAt: createdAt ?? this.createdAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (messageId.present) { + map['message_id'] = Variable(messageId.value); + } + if (contactId.present) { + map['contact_id'] = Variable(contactId.value); + } + if (content.present) { + map['content'] = Variable(content.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('MessageHistoriesCompanion(') + ..write('id: $id, ') + ..write('messageId: $messageId, ') + ..write('contactId: $contactId, ') + ..write('content: $content, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } +} + +class Reactions extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + Reactions(this.attachedDatabase, [this._alias]); + late final GeneratedColumn messageId = GeneratedColumn( + 'message_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES messages(message_id)ON DELETE CASCADE', + ); + late final GeneratedColumn emoji = GeneratedColumn( + 'emoji', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn senderId = GeneratedColumn( + 'sender_id', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL REFERENCES contacts(user_id)ON DELETE CASCADE', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [messageId, emoji, senderId, createdAt]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'reactions'; + @override + Set get $primaryKey => {messageId, senderId, emoji}; + @override + ReactionsData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return ReactionsData( + messageId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}message_id'], + )!, + emoji: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}emoji'], + )!, + senderId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}sender_id'], + ), + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + Reactions createAlias(String alias) { + return Reactions(attachedDatabase, alias); + } + + @override + List get customConstraints => const [ + 'PRIMARY KEY(message_id, sender_id, emoji)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class ReactionsData extends DataClass implements Insertable { + final String messageId; + final String emoji; + final int? senderId; + final int createdAt; + const ReactionsData({ + required this.messageId, + required this.emoji, + this.senderId, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['message_id'] = Variable(messageId); + map['emoji'] = Variable(emoji); + if (!nullToAbsent || senderId != null) { + map['sender_id'] = Variable(senderId); + } + map['created_at'] = Variable(createdAt); + return map; + } + + ReactionsCompanion toCompanion(bool nullToAbsent) { + return ReactionsCompanion( + messageId: Value(messageId), + emoji: Value(emoji), + senderId: senderId == null && nullToAbsent + ? const Value.absent() + : Value(senderId), + createdAt: Value(createdAt), + ); + } + + factory ReactionsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return ReactionsData( + messageId: serializer.fromJson(json['messageId']), + emoji: serializer.fromJson(json['emoji']), + senderId: serializer.fromJson(json['senderId']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'messageId': serializer.toJson(messageId), + 'emoji': serializer.toJson(emoji), + 'senderId': serializer.toJson(senderId), + 'createdAt': serializer.toJson(createdAt), + }; + } + + ReactionsData copyWith({ + String? messageId, + String? emoji, + Value senderId = const Value.absent(), + int? createdAt, + }) => ReactionsData( + messageId: messageId ?? this.messageId, + emoji: emoji ?? this.emoji, + senderId: senderId.present ? senderId.value : this.senderId, + createdAt: createdAt ?? this.createdAt, + ); + ReactionsData copyWithCompanion(ReactionsCompanion data) { + return ReactionsData( + messageId: data.messageId.present ? data.messageId.value : this.messageId, + emoji: data.emoji.present ? data.emoji.value : this.emoji, + senderId: data.senderId.present ? data.senderId.value : this.senderId, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('ReactionsData(') + ..write('messageId: $messageId, ') + ..write('emoji: $emoji, ') + ..write('senderId: $senderId, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(messageId, emoji, senderId, createdAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is ReactionsData && + other.messageId == this.messageId && + other.emoji == this.emoji && + other.senderId == this.senderId && + other.createdAt == this.createdAt); +} + +class ReactionsCompanion extends UpdateCompanion { + final Value messageId; + final Value emoji; + final Value senderId; + final Value createdAt; + final Value rowid; + const ReactionsCompanion({ + this.messageId = const Value.absent(), + this.emoji = const Value.absent(), + this.senderId = const Value.absent(), + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }); + ReactionsCompanion.insert({ + required String messageId, + required String emoji, + this.senderId = const Value.absent(), + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }) : messageId = Value(messageId), + emoji = Value(emoji); + static Insertable custom({ + Expression? messageId, + Expression? emoji, + Expression? senderId, + Expression? createdAt, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (messageId != null) 'message_id': messageId, + if (emoji != null) 'emoji': emoji, + if (senderId != null) 'sender_id': senderId, + if (createdAt != null) 'created_at': createdAt, + if (rowid != null) 'rowid': rowid, + }); + } + + ReactionsCompanion copyWith({ + Value? messageId, + Value? emoji, + Value? senderId, + Value? createdAt, + Value? rowid, + }) { + return ReactionsCompanion( + messageId: messageId ?? this.messageId, + emoji: emoji ?? this.emoji, + senderId: senderId ?? this.senderId, + createdAt: createdAt ?? this.createdAt, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (messageId.present) { + map['message_id'] = Variable(messageId.value); + } + if (emoji.present) { + map['emoji'] = Variable(emoji.value); + } + if (senderId.present) { + map['sender_id'] = Variable(senderId.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('ReactionsCompanion(') + ..write('messageId: $messageId, ') + ..write('emoji: $emoji, ') + ..write('senderId: $senderId, ') + ..write('createdAt: $createdAt, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class GroupMembers extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + GroupMembers(this.attachedDatabase, [this._alias]); + late final GeneratedColumn groupId = GeneratedColumn( + 'group_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES "groups"(group_id)ON DELETE CASCADE', + ); + late final GeneratedColumn contactId = GeneratedColumn( + 'contact_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL REFERENCES contacts(user_id)', + ); + late final GeneratedColumn memberState = GeneratedColumn( + 'member_state', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn groupPublicKey = + GeneratedColumn( + 'group_public_key', + aliasedName, + true, + type: DriftSqlType.blob, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn lastChatOpened = GeneratedColumn( + 'last_chat_opened', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn lastTypeIndicator = GeneratedColumn( + 'last_type_indicator', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn lastMessage = GeneratedColumn( + 'last_message', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [ + groupId, + contactId, + memberState, + groupPublicKey, + lastChatOpened, + lastTypeIndicator, + lastMessage, + createdAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'group_members'; + @override + Set get $primaryKey => {groupId, contactId}; + @override + GroupMembersData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return GroupMembersData( + groupId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}group_id'], + )!, + contactId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}contact_id'], + )!, + memberState: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}member_state'], + ), + groupPublicKey: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}group_public_key'], + ), + lastChatOpened: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}last_chat_opened'], + ), + lastTypeIndicator: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}last_type_indicator'], + ), + lastMessage: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}last_message'], + ), + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + GroupMembers createAlias(String alias) { + return GroupMembers(attachedDatabase, alias); + } + + @override + List get customConstraints => const [ + 'PRIMARY KEY(group_id, contact_id)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class GroupMembersData extends DataClass + implements Insertable { + final String groupId; + final int contactId; + final String? memberState; + final i2.Uint8List? groupPublicKey; + final int? lastChatOpened; + final int? lastTypeIndicator; + final int? lastMessage; + final int createdAt; + const GroupMembersData({ + required this.groupId, + required this.contactId, + this.memberState, + this.groupPublicKey, + this.lastChatOpened, + this.lastTypeIndicator, + this.lastMessage, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['group_id'] = Variable(groupId); + map['contact_id'] = Variable(contactId); + if (!nullToAbsent || memberState != null) { + map['member_state'] = Variable(memberState); + } + if (!nullToAbsent || groupPublicKey != null) { + map['group_public_key'] = Variable(groupPublicKey); + } + if (!nullToAbsent || lastChatOpened != null) { + map['last_chat_opened'] = Variable(lastChatOpened); + } + if (!nullToAbsent || lastTypeIndicator != null) { + map['last_type_indicator'] = Variable(lastTypeIndicator); + } + if (!nullToAbsent || lastMessage != null) { + map['last_message'] = Variable(lastMessage); + } + map['created_at'] = Variable(createdAt); + return map; + } + + GroupMembersCompanion toCompanion(bool nullToAbsent) { + return GroupMembersCompanion( + groupId: Value(groupId), + contactId: Value(contactId), + memberState: memberState == null && nullToAbsent + ? const Value.absent() + : Value(memberState), + groupPublicKey: groupPublicKey == null && nullToAbsent + ? const Value.absent() + : Value(groupPublicKey), + lastChatOpened: lastChatOpened == null && nullToAbsent + ? const Value.absent() + : Value(lastChatOpened), + lastTypeIndicator: lastTypeIndicator == null && nullToAbsent + ? const Value.absent() + : Value(lastTypeIndicator), + lastMessage: lastMessage == null && nullToAbsent + ? const Value.absent() + : Value(lastMessage), + createdAt: Value(createdAt), + ); + } + + factory GroupMembersData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return GroupMembersData( + groupId: serializer.fromJson(json['groupId']), + contactId: serializer.fromJson(json['contactId']), + memberState: serializer.fromJson(json['memberState']), + groupPublicKey: serializer.fromJson( + json['groupPublicKey'], + ), + lastChatOpened: serializer.fromJson(json['lastChatOpened']), + lastTypeIndicator: serializer.fromJson(json['lastTypeIndicator']), + lastMessage: serializer.fromJson(json['lastMessage']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'groupId': serializer.toJson(groupId), + 'contactId': serializer.toJson(contactId), + 'memberState': serializer.toJson(memberState), + 'groupPublicKey': serializer.toJson(groupPublicKey), + 'lastChatOpened': serializer.toJson(lastChatOpened), + 'lastTypeIndicator': serializer.toJson(lastTypeIndicator), + 'lastMessage': serializer.toJson(lastMessage), + 'createdAt': serializer.toJson(createdAt), + }; + } + + GroupMembersData copyWith({ + String? groupId, + int? contactId, + Value memberState = const Value.absent(), + Value groupPublicKey = const Value.absent(), + Value lastChatOpened = const Value.absent(), + Value lastTypeIndicator = const Value.absent(), + Value lastMessage = const Value.absent(), + int? createdAt, + }) => GroupMembersData( + groupId: groupId ?? this.groupId, + contactId: contactId ?? this.contactId, + memberState: memberState.present ? memberState.value : this.memberState, + groupPublicKey: groupPublicKey.present + ? groupPublicKey.value + : this.groupPublicKey, + lastChatOpened: lastChatOpened.present + ? lastChatOpened.value + : this.lastChatOpened, + lastTypeIndicator: lastTypeIndicator.present + ? lastTypeIndicator.value + : this.lastTypeIndicator, + lastMessage: lastMessage.present ? lastMessage.value : this.lastMessage, + createdAt: createdAt ?? this.createdAt, + ); + GroupMembersData copyWithCompanion(GroupMembersCompanion data) { + return GroupMembersData( + groupId: data.groupId.present ? data.groupId.value : this.groupId, + contactId: data.contactId.present ? data.contactId.value : this.contactId, + memberState: data.memberState.present + ? data.memberState.value + : this.memberState, + groupPublicKey: data.groupPublicKey.present + ? data.groupPublicKey.value + : this.groupPublicKey, + lastChatOpened: data.lastChatOpened.present + ? data.lastChatOpened.value + : this.lastChatOpened, + lastTypeIndicator: data.lastTypeIndicator.present + ? data.lastTypeIndicator.value + : this.lastTypeIndicator, + lastMessage: data.lastMessage.present + ? data.lastMessage.value + : this.lastMessage, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('GroupMembersData(') + ..write('groupId: $groupId, ') + ..write('contactId: $contactId, ') + ..write('memberState: $memberState, ') + ..write('groupPublicKey: $groupPublicKey, ') + ..write('lastChatOpened: $lastChatOpened, ') + ..write('lastTypeIndicator: $lastTypeIndicator, ') + ..write('lastMessage: $lastMessage, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + groupId, + contactId, + memberState, + $driftBlobEquality.hash(groupPublicKey), + lastChatOpened, + lastTypeIndicator, + lastMessage, + createdAt, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is GroupMembersData && + other.groupId == this.groupId && + other.contactId == this.contactId && + other.memberState == this.memberState && + $driftBlobEquality.equals( + other.groupPublicKey, + this.groupPublicKey, + ) && + other.lastChatOpened == this.lastChatOpened && + other.lastTypeIndicator == this.lastTypeIndicator && + other.lastMessage == this.lastMessage && + other.createdAt == this.createdAt); +} + +class GroupMembersCompanion extends UpdateCompanion { + final Value groupId; + final Value contactId; + final Value memberState; + final Value groupPublicKey; + final Value lastChatOpened; + final Value lastTypeIndicator; + final Value lastMessage; + final Value createdAt; + final Value rowid; + const GroupMembersCompanion({ + this.groupId = const Value.absent(), + this.contactId = const Value.absent(), + this.memberState = const Value.absent(), + this.groupPublicKey = const Value.absent(), + this.lastChatOpened = const Value.absent(), + this.lastTypeIndicator = const Value.absent(), + this.lastMessage = const Value.absent(), + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }); + GroupMembersCompanion.insert({ + required String groupId, + required int contactId, + this.memberState = const Value.absent(), + this.groupPublicKey = const Value.absent(), + this.lastChatOpened = const Value.absent(), + this.lastTypeIndicator = const Value.absent(), + this.lastMessage = const Value.absent(), + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }) : groupId = Value(groupId), + contactId = Value(contactId); + static Insertable custom({ + Expression? groupId, + Expression? contactId, + Expression? memberState, + Expression? groupPublicKey, + Expression? lastChatOpened, + Expression? lastTypeIndicator, + Expression? lastMessage, + Expression? createdAt, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (groupId != null) 'group_id': groupId, + if (contactId != null) 'contact_id': contactId, + if (memberState != null) 'member_state': memberState, + if (groupPublicKey != null) 'group_public_key': groupPublicKey, + if (lastChatOpened != null) 'last_chat_opened': lastChatOpened, + if (lastTypeIndicator != null) 'last_type_indicator': lastTypeIndicator, + if (lastMessage != null) 'last_message': lastMessage, + if (createdAt != null) 'created_at': createdAt, + if (rowid != null) 'rowid': rowid, + }); + } + + GroupMembersCompanion copyWith({ + Value? groupId, + Value? contactId, + Value? memberState, + Value? groupPublicKey, + Value? lastChatOpened, + Value? lastTypeIndicator, + Value? lastMessage, + Value? createdAt, + Value? rowid, + }) { + return GroupMembersCompanion( + groupId: groupId ?? this.groupId, + contactId: contactId ?? this.contactId, + memberState: memberState ?? this.memberState, + groupPublicKey: groupPublicKey ?? this.groupPublicKey, + lastChatOpened: lastChatOpened ?? this.lastChatOpened, + lastTypeIndicator: lastTypeIndicator ?? this.lastTypeIndicator, + lastMessage: lastMessage ?? this.lastMessage, + createdAt: createdAt ?? this.createdAt, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (groupId.present) { + map['group_id'] = Variable(groupId.value); + } + if (contactId.present) { + map['contact_id'] = Variable(contactId.value); + } + if (memberState.present) { + map['member_state'] = Variable(memberState.value); + } + if (groupPublicKey.present) { + map['group_public_key'] = Variable(groupPublicKey.value); + } + if (lastChatOpened.present) { + map['last_chat_opened'] = Variable(lastChatOpened.value); + } + if (lastTypeIndicator.present) { + map['last_type_indicator'] = Variable(lastTypeIndicator.value); + } + if (lastMessage.present) { + map['last_message'] = Variable(lastMessage.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('GroupMembersCompanion(') + ..write('groupId: $groupId, ') + ..write('contactId: $contactId, ') + ..write('memberState: $memberState, ') + ..write('groupPublicKey: $groupPublicKey, ') + ..write('lastChatOpened: $lastChatOpened, ') + ..write('lastTypeIndicator: $lastTypeIndicator, ') + ..write('lastMessage: $lastMessage, ') + ..write('createdAt: $createdAt, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class Receipts extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + Receipts(this.attachedDatabase, [this._alias]); + late final GeneratedColumn receiptId = GeneratedColumn( + 'receipt_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn contactId = GeneratedColumn( + 'contact_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES contacts(user_id)ON DELETE CASCADE', + ); + late final GeneratedColumn messageId = GeneratedColumn( + 'message_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL REFERENCES messages(message_id)ON DELETE CASCADE', + ); + late final GeneratedColumn message = + GeneratedColumn( + 'message', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn contactWillSendsReceipt = + GeneratedColumn( + 'contact_will_sends_receipt', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 1 CHECK (contact_will_sends_receipt IN (0, 1))', + defaultValue: const CustomExpression('1'), + ); + late final GeneratedColumn + willBeRetriedByMediaUpload = GeneratedColumn( + 'will_be_retried_by_media_upload', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 CHECK (will_be_retried_by_media_upload IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn markForRetry = GeneratedColumn( + 'mark_for_retry', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn markForRetryAfterAccepted = + GeneratedColumn( + 'mark_for_retry_after_accepted', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn ackByServerAt = GeneratedColumn( + 'ack_by_server_at', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn retryCount = GeneratedColumn( + 'retry_count', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn lastRetry = GeneratedColumn( + 'last_retry', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [ + receiptId, + contactId, + messageId, + message, + contactWillSendsReceipt, + willBeRetriedByMediaUpload, + markForRetry, + markForRetryAfterAccepted, + ackByServerAt, + retryCount, + lastRetry, + createdAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'receipts'; + @override + Set get $primaryKey => {receiptId}; + @override + ReceiptsData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return ReceiptsData( + receiptId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}receipt_id'], + )!, + contactId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}contact_id'], + )!, + messageId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}message_id'], + ), + message: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}message'], + )!, + contactWillSendsReceipt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}contact_will_sends_receipt'], + )!, + willBeRetriedByMediaUpload: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}will_be_retried_by_media_upload'], + )!, + markForRetry: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}mark_for_retry'], + ), + markForRetryAfterAccepted: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}mark_for_retry_after_accepted'], + ), + ackByServerAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}ack_by_server_at'], + ), + retryCount: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}retry_count'], + )!, + lastRetry: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}last_retry'], + ), + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + Receipts createAlias(String alias) { + return Receipts(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(receipt_id)']; + @override + bool get dontWriteConstraints => true; +} + +class ReceiptsData extends DataClass implements Insertable { + final String receiptId; + final int contactId; + final String? messageId; + final i2.Uint8List message; + final int contactWillSendsReceipt; + final int willBeRetriedByMediaUpload; + final int? markForRetry; + final int? markForRetryAfterAccepted; + final int? ackByServerAt; + final int retryCount; + final int? lastRetry; + final int createdAt; + const ReceiptsData({ + required this.receiptId, + required this.contactId, + this.messageId, + required this.message, + required this.contactWillSendsReceipt, + required this.willBeRetriedByMediaUpload, + this.markForRetry, + this.markForRetryAfterAccepted, + this.ackByServerAt, + required this.retryCount, + this.lastRetry, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['receipt_id'] = Variable(receiptId); + map['contact_id'] = Variable(contactId); + if (!nullToAbsent || messageId != null) { + map['message_id'] = Variable(messageId); + } + map['message'] = Variable(message); + map['contact_will_sends_receipt'] = Variable(contactWillSendsReceipt); + map['will_be_retried_by_media_upload'] = Variable( + willBeRetriedByMediaUpload, + ); + if (!nullToAbsent || markForRetry != null) { + map['mark_for_retry'] = Variable(markForRetry); + } + if (!nullToAbsent || markForRetryAfterAccepted != null) { + map['mark_for_retry_after_accepted'] = Variable( + markForRetryAfterAccepted, + ); + } + if (!nullToAbsent || ackByServerAt != null) { + map['ack_by_server_at'] = Variable(ackByServerAt); + } + map['retry_count'] = Variable(retryCount); + if (!nullToAbsent || lastRetry != null) { + map['last_retry'] = Variable(lastRetry); + } + map['created_at'] = Variable(createdAt); + return map; + } + + ReceiptsCompanion toCompanion(bool nullToAbsent) { + return ReceiptsCompanion( + receiptId: Value(receiptId), + contactId: Value(contactId), + messageId: messageId == null && nullToAbsent + ? const Value.absent() + : Value(messageId), + message: Value(message), + contactWillSendsReceipt: Value(contactWillSendsReceipt), + willBeRetriedByMediaUpload: Value(willBeRetriedByMediaUpload), + markForRetry: markForRetry == null && nullToAbsent + ? const Value.absent() + : Value(markForRetry), + markForRetryAfterAccepted: + markForRetryAfterAccepted == null && nullToAbsent + ? const Value.absent() + : Value(markForRetryAfterAccepted), + ackByServerAt: ackByServerAt == null && nullToAbsent + ? const Value.absent() + : Value(ackByServerAt), + retryCount: Value(retryCount), + lastRetry: lastRetry == null && nullToAbsent + ? const Value.absent() + : Value(lastRetry), + createdAt: Value(createdAt), + ); + } + + factory ReceiptsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return ReceiptsData( + receiptId: serializer.fromJson(json['receiptId']), + contactId: serializer.fromJson(json['contactId']), + messageId: serializer.fromJson(json['messageId']), + message: serializer.fromJson(json['message']), + contactWillSendsReceipt: serializer.fromJson( + json['contactWillSendsReceipt'], + ), + willBeRetriedByMediaUpload: serializer.fromJson( + json['willBeRetriedByMediaUpload'], + ), + markForRetry: serializer.fromJson(json['markForRetry']), + markForRetryAfterAccepted: serializer.fromJson( + json['markForRetryAfterAccepted'], + ), + ackByServerAt: serializer.fromJson(json['ackByServerAt']), + retryCount: serializer.fromJson(json['retryCount']), + lastRetry: serializer.fromJson(json['lastRetry']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'receiptId': serializer.toJson(receiptId), + 'contactId': serializer.toJson(contactId), + 'messageId': serializer.toJson(messageId), + 'message': serializer.toJson(message), + 'contactWillSendsReceipt': serializer.toJson( + contactWillSendsReceipt, + ), + 'willBeRetriedByMediaUpload': serializer.toJson( + willBeRetriedByMediaUpload, + ), + 'markForRetry': serializer.toJson(markForRetry), + 'markForRetryAfterAccepted': serializer.toJson( + markForRetryAfterAccepted, + ), + 'ackByServerAt': serializer.toJson(ackByServerAt), + 'retryCount': serializer.toJson(retryCount), + 'lastRetry': serializer.toJson(lastRetry), + 'createdAt': serializer.toJson(createdAt), + }; + } + + ReceiptsData copyWith({ + String? receiptId, + int? contactId, + Value messageId = const Value.absent(), + i2.Uint8List? message, + int? contactWillSendsReceipt, + int? willBeRetriedByMediaUpload, + Value markForRetry = const Value.absent(), + Value markForRetryAfterAccepted = const Value.absent(), + Value ackByServerAt = const Value.absent(), + int? retryCount, + Value lastRetry = const Value.absent(), + int? createdAt, + }) => ReceiptsData( + receiptId: receiptId ?? this.receiptId, + contactId: contactId ?? this.contactId, + messageId: messageId.present ? messageId.value : this.messageId, + message: message ?? this.message, + contactWillSendsReceipt: + contactWillSendsReceipt ?? this.contactWillSendsReceipt, + willBeRetriedByMediaUpload: + willBeRetriedByMediaUpload ?? this.willBeRetriedByMediaUpload, + markForRetry: markForRetry.present ? markForRetry.value : this.markForRetry, + markForRetryAfterAccepted: markForRetryAfterAccepted.present + ? markForRetryAfterAccepted.value + : this.markForRetryAfterAccepted, + ackByServerAt: ackByServerAt.present + ? ackByServerAt.value + : this.ackByServerAt, + retryCount: retryCount ?? this.retryCount, + lastRetry: lastRetry.present ? lastRetry.value : this.lastRetry, + createdAt: createdAt ?? this.createdAt, + ); + ReceiptsData copyWithCompanion(ReceiptsCompanion data) { + return ReceiptsData( + receiptId: data.receiptId.present ? data.receiptId.value : this.receiptId, + contactId: data.contactId.present ? data.contactId.value : this.contactId, + messageId: data.messageId.present ? data.messageId.value : this.messageId, + message: data.message.present ? data.message.value : this.message, + contactWillSendsReceipt: data.contactWillSendsReceipt.present + ? data.contactWillSendsReceipt.value + : this.contactWillSendsReceipt, + willBeRetriedByMediaUpload: data.willBeRetriedByMediaUpload.present + ? data.willBeRetriedByMediaUpload.value + : this.willBeRetriedByMediaUpload, + markForRetry: data.markForRetry.present + ? data.markForRetry.value + : this.markForRetry, + markForRetryAfterAccepted: data.markForRetryAfterAccepted.present + ? data.markForRetryAfterAccepted.value + : this.markForRetryAfterAccepted, + ackByServerAt: data.ackByServerAt.present + ? data.ackByServerAt.value + : this.ackByServerAt, + retryCount: data.retryCount.present + ? data.retryCount.value + : this.retryCount, + lastRetry: data.lastRetry.present ? data.lastRetry.value : this.lastRetry, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('ReceiptsData(') + ..write('receiptId: $receiptId, ') + ..write('contactId: $contactId, ') + ..write('messageId: $messageId, ') + ..write('message: $message, ') + ..write('contactWillSendsReceipt: $contactWillSendsReceipt, ') + ..write('willBeRetriedByMediaUpload: $willBeRetriedByMediaUpload, ') + ..write('markForRetry: $markForRetry, ') + ..write('markForRetryAfterAccepted: $markForRetryAfterAccepted, ') + ..write('ackByServerAt: $ackByServerAt, ') + ..write('retryCount: $retryCount, ') + ..write('lastRetry: $lastRetry, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + receiptId, + contactId, + messageId, + $driftBlobEquality.hash(message), + contactWillSendsReceipt, + willBeRetriedByMediaUpload, + markForRetry, + markForRetryAfterAccepted, + ackByServerAt, + retryCount, + lastRetry, + createdAt, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is ReceiptsData && + other.receiptId == this.receiptId && + other.contactId == this.contactId && + other.messageId == this.messageId && + $driftBlobEquality.equals(other.message, this.message) && + other.contactWillSendsReceipt == this.contactWillSendsReceipt && + other.willBeRetriedByMediaUpload == this.willBeRetriedByMediaUpload && + other.markForRetry == this.markForRetry && + other.markForRetryAfterAccepted == this.markForRetryAfterAccepted && + other.ackByServerAt == this.ackByServerAt && + other.retryCount == this.retryCount && + other.lastRetry == this.lastRetry && + other.createdAt == this.createdAt); +} + +class ReceiptsCompanion extends UpdateCompanion { + final Value receiptId; + final Value contactId; + final Value messageId; + final Value message; + final Value contactWillSendsReceipt; + final Value willBeRetriedByMediaUpload; + final Value markForRetry; + final Value markForRetryAfterAccepted; + final Value ackByServerAt; + final Value retryCount; + final Value lastRetry; + final Value createdAt; + final Value rowid; + const ReceiptsCompanion({ + this.receiptId = const Value.absent(), + this.contactId = const Value.absent(), + this.messageId = const Value.absent(), + this.message = const Value.absent(), + this.contactWillSendsReceipt = const Value.absent(), + this.willBeRetriedByMediaUpload = const Value.absent(), + this.markForRetry = const Value.absent(), + this.markForRetryAfterAccepted = const Value.absent(), + this.ackByServerAt = const Value.absent(), + this.retryCount = const Value.absent(), + this.lastRetry = const Value.absent(), + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }); + ReceiptsCompanion.insert({ + required String receiptId, + required int contactId, + this.messageId = const Value.absent(), + required i2.Uint8List message, + this.contactWillSendsReceipt = const Value.absent(), + this.willBeRetriedByMediaUpload = const Value.absent(), + this.markForRetry = const Value.absent(), + this.markForRetryAfterAccepted = const Value.absent(), + this.ackByServerAt = const Value.absent(), + this.retryCount = const Value.absent(), + this.lastRetry = const Value.absent(), + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }) : receiptId = Value(receiptId), + contactId = Value(contactId), + message = Value(message); + static Insertable custom({ + Expression? receiptId, + Expression? contactId, + Expression? messageId, + Expression? message, + Expression? contactWillSendsReceipt, + Expression? willBeRetriedByMediaUpload, + Expression? markForRetry, + Expression? markForRetryAfterAccepted, + Expression? ackByServerAt, + Expression? retryCount, + Expression? lastRetry, + Expression? createdAt, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (receiptId != null) 'receipt_id': receiptId, + if (contactId != null) 'contact_id': contactId, + if (messageId != null) 'message_id': messageId, + if (message != null) 'message': message, + if (contactWillSendsReceipt != null) + 'contact_will_sends_receipt': contactWillSendsReceipt, + if (willBeRetriedByMediaUpload != null) + 'will_be_retried_by_media_upload': willBeRetriedByMediaUpload, + if (markForRetry != null) 'mark_for_retry': markForRetry, + if (markForRetryAfterAccepted != null) + 'mark_for_retry_after_accepted': markForRetryAfterAccepted, + if (ackByServerAt != null) 'ack_by_server_at': ackByServerAt, + if (retryCount != null) 'retry_count': retryCount, + if (lastRetry != null) 'last_retry': lastRetry, + if (createdAt != null) 'created_at': createdAt, + if (rowid != null) 'rowid': rowid, + }); + } + + ReceiptsCompanion copyWith({ + Value? receiptId, + Value? contactId, + Value? messageId, + Value? message, + Value? contactWillSendsReceipt, + Value? willBeRetriedByMediaUpload, + Value? markForRetry, + Value? markForRetryAfterAccepted, + Value? ackByServerAt, + Value? retryCount, + Value? lastRetry, + Value? createdAt, + Value? rowid, + }) { + return ReceiptsCompanion( + receiptId: receiptId ?? this.receiptId, + contactId: contactId ?? this.contactId, + messageId: messageId ?? this.messageId, + message: message ?? this.message, + contactWillSendsReceipt: + contactWillSendsReceipt ?? this.contactWillSendsReceipt, + willBeRetriedByMediaUpload: + willBeRetriedByMediaUpload ?? this.willBeRetriedByMediaUpload, + markForRetry: markForRetry ?? this.markForRetry, + markForRetryAfterAccepted: + markForRetryAfterAccepted ?? this.markForRetryAfterAccepted, + ackByServerAt: ackByServerAt ?? this.ackByServerAt, + retryCount: retryCount ?? this.retryCount, + lastRetry: lastRetry ?? this.lastRetry, + createdAt: createdAt ?? this.createdAt, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (receiptId.present) { + map['receipt_id'] = Variable(receiptId.value); + } + if (contactId.present) { + map['contact_id'] = Variable(contactId.value); + } + if (messageId.present) { + map['message_id'] = Variable(messageId.value); + } + if (message.present) { + map['message'] = Variable(message.value); + } + if (contactWillSendsReceipt.present) { + map['contact_will_sends_receipt'] = Variable( + contactWillSendsReceipt.value, + ); + } + if (willBeRetriedByMediaUpload.present) { + map['will_be_retried_by_media_upload'] = Variable( + willBeRetriedByMediaUpload.value, + ); + } + if (markForRetry.present) { + map['mark_for_retry'] = Variable(markForRetry.value); + } + if (markForRetryAfterAccepted.present) { + map['mark_for_retry_after_accepted'] = Variable( + markForRetryAfterAccepted.value, + ); + } + if (ackByServerAt.present) { + map['ack_by_server_at'] = Variable(ackByServerAt.value); + } + if (retryCount.present) { + map['retry_count'] = Variable(retryCount.value); + } + if (lastRetry.present) { + map['last_retry'] = Variable(lastRetry.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('ReceiptsCompanion(') + ..write('receiptId: $receiptId, ') + ..write('contactId: $contactId, ') + ..write('messageId: $messageId, ') + ..write('message: $message, ') + ..write('contactWillSendsReceipt: $contactWillSendsReceipt, ') + ..write('willBeRetriedByMediaUpload: $willBeRetriedByMediaUpload, ') + ..write('markForRetry: $markForRetry, ') + ..write('markForRetryAfterAccepted: $markForRetryAfterAccepted, ') + ..write('ackByServerAt: $ackByServerAt, ') + ..write('retryCount: $retryCount, ') + ..write('lastRetry: $lastRetry, ') + ..write('createdAt: $createdAt, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class ReceivedReceipts extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + ReceivedReceipts(this.attachedDatabase, [this._alias]); + late final GeneratedColumn receiptId = GeneratedColumn( + 'receipt_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [receiptId, createdAt]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'received_receipts'; + @override + Set get $primaryKey => {receiptId}; + @override + ReceivedReceiptsData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return ReceivedReceiptsData( + receiptId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}receipt_id'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + ReceivedReceipts createAlias(String alias) { + return ReceivedReceipts(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(receipt_id)']; + @override + bool get dontWriteConstraints => true; +} + +class ReceivedReceiptsData extends DataClass + implements Insertable { + final String receiptId; + final int createdAt; + const ReceivedReceiptsData({ + required this.receiptId, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['receipt_id'] = Variable(receiptId); + map['created_at'] = Variable(createdAt); + return map; + } + + ReceivedReceiptsCompanion toCompanion(bool nullToAbsent) { + return ReceivedReceiptsCompanion( + receiptId: Value(receiptId), + createdAt: Value(createdAt), + ); + } + + factory ReceivedReceiptsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return ReceivedReceiptsData( + receiptId: serializer.fromJson(json['receiptId']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'receiptId': serializer.toJson(receiptId), + 'createdAt': serializer.toJson(createdAt), + }; + } + + ReceivedReceiptsData copyWith({String? receiptId, int? createdAt}) => + ReceivedReceiptsData( + receiptId: receiptId ?? this.receiptId, + createdAt: createdAt ?? this.createdAt, + ); + ReceivedReceiptsData copyWithCompanion(ReceivedReceiptsCompanion data) { + return ReceivedReceiptsData( + receiptId: data.receiptId.present ? data.receiptId.value : this.receiptId, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('ReceivedReceiptsData(') + ..write('receiptId: $receiptId, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(receiptId, createdAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is ReceivedReceiptsData && + other.receiptId == this.receiptId && + other.createdAt == this.createdAt); +} + +class ReceivedReceiptsCompanion extends UpdateCompanion { + final Value receiptId; + final Value createdAt; + final Value rowid; + const ReceivedReceiptsCompanion({ + this.receiptId = const Value.absent(), + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }); + ReceivedReceiptsCompanion.insert({ + required String receiptId, + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }) : receiptId = Value(receiptId); + static Insertable custom({ + Expression? receiptId, + Expression? createdAt, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (receiptId != null) 'receipt_id': receiptId, + if (createdAt != null) 'created_at': createdAt, + if (rowid != null) 'rowid': rowid, + }); + } + + ReceivedReceiptsCompanion copyWith({ + Value? receiptId, + Value? createdAt, + Value? rowid, + }) { + return ReceivedReceiptsCompanion( + receiptId: receiptId ?? this.receiptId, + createdAt: createdAt ?? this.createdAt, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (receiptId.present) { + map['receipt_id'] = Variable(receiptId.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('ReceivedReceiptsCompanion(') + ..write('receiptId: $receiptId, ') + ..write('createdAt: $createdAt, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class SignalIdentityKeyStores extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + SignalIdentityKeyStores(this.attachedDatabase, [this._alias]); + late final GeneratedColumn deviceId = GeneratedColumn( + 'device_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn identityKey = + GeneratedColumn( + 'identity_key', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [ + deviceId, + name, + identityKey, + createdAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'signal_identity_key_stores'; + @override + Set get $primaryKey => {deviceId, name}; + @override + SignalIdentityKeyStoresData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return SignalIdentityKeyStoresData( + deviceId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}device_id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + identityKey: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}identity_key'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + SignalIdentityKeyStores createAlias(String alias) { + return SignalIdentityKeyStores(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(device_id, name)']; + @override + bool get dontWriteConstraints => true; +} + +class SignalIdentityKeyStoresData extends DataClass + implements Insertable { + final int deviceId; + final String name; + final i2.Uint8List identityKey; + final int createdAt; + const SignalIdentityKeyStoresData({ + required this.deviceId, + required this.name, + required this.identityKey, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['device_id'] = Variable(deviceId); + map['name'] = Variable(name); + map['identity_key'] = Variable(identityKey); + map['created_at'] = Variable(createdAt); + return map; + } + + SignalIdentityKeyStoresCompanion toCompanion(bool nullToAbsent) { + return SignalIdentityKeyStoresCompanion( + deviceId: Value(deviceId), + name: Value(name), + identityKey: Value(identityKey), + createdAt: Value(createdAt), + ); + } + + factory SignalIdentityKeyStoresData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return SignalIdentityKeyStoresData( + deviceId: serializer.fromJson(json['deviceId']), + name: serializer.fromJson(json['name']), + identityKey: serializer.fromJson(json['identityKey']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'deviceId': serializer.toJson(deviceId), + 'name': serializer.toJson(name), + 'identityKey': serializer.toJson(identityKey), + 'createdAt': serializer.toJson(createdAt), + }; + } + + SignalIdentityKeyStoresData copyWith({ + int? deviceId, + String? name, + i2.Uint8List? identityKey, + int? createdAt, + }) => SignalIdentityKeyStoresData( + deviceId: deviceId ?? this.deviceId, + name: name ?? this.name, + identityKey: identityKey ?? this.identityKey, + createdAt: createdAt ?? this.createdAt, + ); + SignalIdentityKeyStoresData copyWithCompanion( + SignalIdentityKeyStoresCompanion data, + ) { + return SignalIdentityKeyStoresData( + deviceId: data.deviceId.present ? data.deviceId.value : this.deviceId, + name: data.name.present ? data.name.value : this.name, + identityKey: data.identityKey.present + ? data.identityKey.value + : this.identityKey, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('SignalIdentityKeyStoresData(') + ..write('deviceId: $deviceId, ') + ..write('name: $name, ') + ..write('identityKey: $identityKey, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + deviceId, + name, + $driftBlobEquality.hash(identityKey), + createdAt, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is SignalIdentityKeyStoresData && + other.deviceId == this.deviceId && + other.name == this.name && + $driftBlobEquality.equals(other.identityKey, this.identityKey) && + other.createdAt == this.createdAt); +} + +class SignalIdentityKeyStoresCompanion + extends UpdateCompanion { + final Value deviceId; + final Value name; + final Value identityKey; + final Value createdAt; + final Value rowid; + const SignalIdentityKeyStoresCompanion({ + this.deviceId = const Value.absent(), + this.name = const Value.absent(), + this.identityKey = const Value.absent(), + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }); + SignalIdentityKeyStoresCompanion.insert({ + required int deviceId, + required String name, + required i2.Uint8List identityKey, + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }) : deviceId = Value(deviceId), + name = Value(name), + identityKey = Value(identityKey); + static Insertable custom({ + Expression? deviceId, + Expression? name, + Expression? identityKey, + Expression? createdAt, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (deviceId != null) 'device_id': deviceId, + if (name != null) 'name': name, + if (identityKey != null) 'identity_key': identityKey, + if (createdAt != null) 'created_at': createdAt, + if (rowid != null) 'rowid': rowid, + }); + } + + SignalIdentityKeyStoresCompanion copyWith({ + Value? deviceId, + Value? name, + Value? identityKey, + Value? createdAt, + Value? rowid, + }) { + return SignalIdentityKeyStoresCompanion( + deviceId: deviceId ?? this.deviceId, + name: name ?? this.name, + identityKey: identityKey ?? this.identityKey, + createdAt: createdAt ?? this.createdAt, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (deviceId.present) { + map['device_id'] = Variable(deviceId.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (identityKey.present) { + map['identity_key'] = Variable(identityKey.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('SignalIdentityKeyStoresCompanion(') + ..write('deviceId: $deviceId, ') + ..write('name: $name, ') + ..write('identityKey: $identityKey, ') + ..write('createdAt: $createdAt, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class SignalPreKeyStores extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + SignalPreKeyStores(this.attachedDatabase, [this._alias]); + late final GeneratedColumn preKeyId = GeneratedColumn( + 'pre_key_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn preKey = + GeneratedColumn( + 'pre_key', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [preKeyId, preKey, createdAt]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'signal_pre_key_stores'; + @override + Set get $primaryKey => {preKeyId}; + @override + SignalPreKeyStoresData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return SignalPreKeyStoresData( + preKeyId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}pre_key_id'], + )!, + preKey: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}pre_key'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + SignalPreKeyStores createAlias(String alias) { + return SignalPreKeyStores(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(pre_key_id)']; + @override + bool get dontWriteConstraints => true; +} + +class SignalPreKeyStoresData extends DataClass + implements Insertable { + final int preKeyId; + final i2.Uint8List preKey; + final int createdAt; + const SignalPreKeyStoresData({ + required this.preKeyId, + required this.preKey, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['pre_key_id'] = Variable(preKeyId); + map['pre_key'] = Variable(preKey); + map['created_at'] = Variable(createdAt); + return map; + } + + SignalPreKeyStoresCompanion toCompanion(bool nullToAbsent) { + return SignalPreKeyStoresCompanion( + preKeyId: Value(preKeyId), + preKey: Value(preKey), + createdAt: Value(createdAt), + ); + } + + factory SignalPreKeyStoresData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return SignalPreKeyStoresData( + preKeyId: serializer.fromJson(json['preKeyId']), + preKey: serializer.fromJson(json['preKey']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'preKeyId': serializer.toJson(preKeyId), + 'preKey': serializer.toJson(preKey), + 'createdAt': serializer.toJson(createdAt), + }; + } + + SignalPreKeyStoresData copyWith({ + int? preKeyId, + i2.Uint8List? preKey, + int? createdAt, + }) => SignalPreKeyStoresData( + preKeyId: preKeyId ?? this.preKeyId, + preKey: preKey ?? this.preKey, + createdAt: createdAt ?? this.createdAt, + ); + SignalPreKeyStoresData copyWithCompanion(SignalPreKeyStoresCompanion data) { + return SignalPreKeyStoresData( + preKeyId: data.preKeyId.present ? data.preKeyId.value : this.preKeyId, + preKey: data.preKey.present ? data.preKey.value : this.preKey, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('SignalPreKeyStoresData(') + ..write('preKeyId: $preKeyId, ') + ..write('preKey: $preKey, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => + Object.hash(preKeyId, $driftBlobEquality.hash(preKey), createdAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is SignalPreKeyStoresData && + other.preKeyId == this.preKeyId && + $driftBlobEquality.equals(other.preKey, this.preKey) && + other.createdAt == this.createdAt); +} + +class SignalPreKeyStoresCompanion + extends UpdateCompanion { + final Value preKeyId; + final Value preKey; + final Value createdAt; + const SignalPreKeyStoresCompanion({ + this.preKeyId = const Value.absent(), + this.preKey = const Value.absent(), + this.createdAt = const Value.absent(), + }); + SignalPreKeyStoresCompanion.insert({ + this.preKeyId = const Value.absent(), + required i2.Uint8List preKey, + this.createdAt = const Value.absent(), + }) : preKey = Value(preKey); + static Insertable custom({ + Expression? preKeyId, + Expression? preKey, + Expression? createdAt, + }) { + return RawValuesInsertable({ + if (preKeyId != null) 'pre_key_id': preKeyId, + if (preKey != null) 'pre_key': preKey, + if (createdAt != null) 'created_at': createdAt, + }); + } + + SignalPreKeyStoresCompanion copyWith({ + Value? preKeyId, + Value? preKey, + Value? createdAt, + }) { + return SignalPreKeyStoresCompanion( + preKeyId: preKeyId ?? this.preKeyId, + preKey: preKey ?? this.preKey, + createdAt: createdAt ?? this.createdAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (preKeyId.present) { + map['pre_key_id'] = Variable(preKeyId.value); + } + if (preKey.present) { + map['pre_key'] = Variable(preKey.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('SignalPreKeyStoresCompanion(') + ..write('preKeyId: $preKeyId, ') + ..write('preKey: $preKey, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } +} + +class SignalSenderKeyStores extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + SignalSenderKeyStores(this.attachedDatabase, [this._alias]); + late final GeneratedColumn senderKeyName = GeneratedColumn( + 'sender_key_name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn senderKey = + GeneratedColumn( + 'sender_key', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + @override + List get $columns => [senderKeyName, senderKey]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'signal_sender_key_stores'; + @override + Set get $primaryKey => {senderKeyName}; + @override + SignalSenderKeyStoresData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return SignalSenderKeyStoresData( + senderKeyName: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}sender_key_name'], + )!, + senderKey: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}sender_key'], + )!, + ); + } + + @override + SignalSenderKeyStores createAlias(String alias) { + return SignalSenderKeyStores(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(sender_key_name)']; + @override + bool get dontWriteConstraints => true; +} + +class SignalSenderKeyStoresData extends DataClass + implements Insertable { + final String senderKeyName; + final i2.Uint8List senderKey; + const SignalSenderKeyStoresData({ + required this.senderKeyName, + required this.senderKey, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['sender_key_name'] = Variable(senderKeyName); + map['sender_key'] = Variable(senderKey); + return map; + } + + SignalSenderKeyStoresCompanion toCompanion(bool nullToAbsent) { + return SignalSenderKeyStoresCompanion( + senderKeyName: Value(senderKeyName), + senderKey: Value(senderKey), + ); + } + + factory SignalSenderKeyStoresData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return SignalSenderKeyStoresData( + senderKeyName: serializer.fromJson(json['senderKeyName']), + senderKey: serializer.fromJson(json['senderKey']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'senderKeyName': serializer.toJson(senderKeyName), + 'senderKey': serializer.toJson(senderKey), + }; + } + + SignalSenderKeyStoresData copyWith({ + String? senderKeyName, + i2.Uint8List? senderKey, + }) => SignalSenderKeyStoresData( + senderKeyName: senderKeyName ?? this.senderKeyName, + senderKey: senderKey ?? this.senderKey, + ); + SignalSenderKeyStoresData copyWithCompanion( + SignalSenderKeyStoresCompanion data, + ) { + return SignalSenderKeyStoresData( + senderKeyName: data.senderKeyName.present + ? data.senderKeyName.value + : this.senderKeyName, + senderKey: data.senderKey.present ? data.senderKey.value : this.senderKey, + ); + } + + @override + String toString() { + return (StringBuffer('SignalSenderKeyStoresData(') + ..write('senderKeyName: $senderKeyName, ') + ..write('senderKey: $senderKey') + ..write(')')) + .toString(); + } + + @override + int get hashCode => + Object.hash(senderKeyName, $driftBlobEquality.hash(senderKey)); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is SignalSenderKeyStoresData && + other.senderKeyName == this.senderKeyName && + $driftBlobEquality.equals(other.senderKey, this.senderKey)); +} + +class SignalSenderKeyStoresCompanion + extends UpdateCompanion { + final Value senderKeyName; + final Value senderKey; + final Value rowid; + const SignalSenderKeyStoresCompanion({ + this.senderKeyName = const Value.absent(), + this.senderKey = const Value.absent(), + this.rowid = const Value.absent(), + }); + SignalSenderKeyStoresCompanion.insert({ + required String senderKeyName, + required i2.Uint8List senderKey, + this.rowid = const Value.absent(), + }) : senderKeyName = Value(senderKeyName), + senderKey = Value(senderKey); + static Insertable custom({ + Expression? senderKeyName, + Expression? senderKey, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (senderKeyName != null) 'sender_key_name': senderKeyName, + if (senderKey != null) 'sender_key': senderKey, + if (rowid != null) 'rowid': rowid, + }); + } + + SignalSenderKeyStoresCompanion copyWith({ + Value? senderKeyName, + Value? senderKey, + Value? rowid, + }) { + return SignalSenderKeyStoresCompanion( + senderKeyName: senderKeyName ?? this.senderKeyName, + senderKey: senderKey ?? this.senderKey, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (senderKeyName.present) { + map['sender_key_name'] = Variable(senderKeyName.value); + } + if (senderKey.present) { + map['sender_key'] = Variable(senderKey.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('SignalSenderKeyStoresCompanion(') + ..write('senderKeyName: $senderKeyName, ') + ..write('senderKey: $senderKey, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class SignalSessionStores extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + SignalSessionStores(this.attachedDatabase, [this._alias]); + late final GeneratedColumn deviceId = GeneratedColumn( + 'device_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn sessionRecord = + GeneratedColumn( + 'session_record', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [ + deviceId, + name, + sessionRecord, + createdAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'signal_session_stores'; + @override + Set get $primaryKey => {deviceId, name}; + @override + SignalSessionStoresData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return SignalSessionStoresData( + deviceId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}device_id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + sessionRecord: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}session_record'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + SignalSessionStores createAlias(String alias) { + return SignalSessionStores(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(device_id, name)']; + @override + bool get dontWriteConstraints => true; +} + +class SignalSessionStoresData extends DataClass + implements Insertable { + final int deviceId; + final String name; + final i2.Uint8List sessionRecord; + final int createdAt; + const SignalSessionStoresData({ + required this.deviceId, + required this.name, + required this.sessionRecord, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['device_id'] = Variable(deviceId); + map['name'] = Variable(name); + map['session_record'] = Variable(sessionRecord); + map['created_at'] = Variable(createdAt); + return map; + } + + SignalSessionStoresCompanion toCompanion(bool nullToAbsent) { + return SignalSessionStoresCompanion( + deviceId: Value(deviceId), + name: Value(name), + sessionRecord: Value(sessionRecord), + createdAt: Value(createdAt), + ); + } + + factory SignalSessionStoresData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return SignalSessionStoresData( + deviceId: serializer.fromJson(json['deviceId']), + name: serializer.fromJson(json['name']), + sessionRecord: serializer.fromJson(json['sessionRecord']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'deviceId': serializer.toJson(deviceId), + 'name': serializer.toJson(name), + 'sessionRecord': serializer.toJson(sessionRecord), + 'createdAt': serializer.toJson(createdAt), + }; + } + + SignalSessionStoresData copyWith({ + int? deviceId, + String? name, + i2.Uint8List? sessionRecord, + int? createdAt, + }) => SignalSessionStoresData( + deviceId: deviceId ?? this.deviceId, + name: name ?? this.name, + sessionRecord: sessionRecord ?? this.sessionRecord, + createdAt: createdAt ?? this.createdAt, + ); + SignalSessionStoresData copyWithCompanion(SignalSessionStoresCompanion data) { + return SignalSessionStoresData( + deviceId: data.deviceId.present ? data.deviceId.value : this.deviceId, + name: data.name.present ? data.name.value : this.name, + sessionRecord: data.sessionRecord.present + ? data.sessionRecord.value + : this.sessionRecord, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('SignalSessionStoresData(') + ..write('deviceId: $deviceId, ') + ..write('name: $name, ') + ..write('sessionRecord: $sessionRecord, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + deviceId, + name, + $driftBlobEquality.hash(sessionRecord), + createdAt, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is SignalSessionStoresData && + other.deviceId == this.deviceId && + other.name == this.name && + $driftBlobEquality.equals(other.sessionRecord, this.sessionRecord) && + other.createdAt == this.createdAt); +} + +class SignalSessionStoresCompanion + extends UpdateCompanion { + final Value deviceId; + final Value name; + final Value sessionRecord; + final Value createdAt; + final Value rowid; + const SignalSessionStoresCompanion({ + this.deviceId = const Value.absent(), + this.name = const Value.absent(), + this.sessionRecord = const Value.absent(), + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }); + SignalSessionStoresCompanion.insert({ + required int deviceId, + required String name, + required i2.Uint8List sessionRecord, + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }) : deviceId = Value(deviceId), + name = Value(name), + sessionRecord = Value(sessionRecord); + static Insertable custom({ + Expression? deviceId, + Expression? name, + Expression? sessionRecord, + Expression? createdAt, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (deviceId != null) 'device_id': deviceId, + if (name != null) 'name': name, + if (sessionRecord != null) 'session_record': sessionRecord, + if (createdAt != null) 'created_at': createdAt, + if (rowid != null) 'rowid': rowid, + }); + } + + SignalSessionStoresCompanion copyWith({ + Value? deviceId, + Value? name, + Value? sessionRecord, + Value? createdAt, + Value? rowid, + }) { + return SignalSessionStoresCompanion( + deviceId: deviceId ?? this.deviceId, + name: name ?? this.name, + sessionRecord: sessionRecord ?? this.sessionRecord, + createdAt: createdAt ?? this.createdAt, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (deviceId.present) { + map['device_id'] = Variable(deviceId.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (sessionRecord.present) { + map['session_record'] = Variable(sessionRecord.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('SignalSessionStoresCompanion(') + ..write('deviceId: $deviceId, ') + ..write('name: $name, ') + ..write('sessionRecord: $sessionRecord, ') + ..write('createdAt: $createdAt, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class SignalSignedPreKeyStores extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + SignalSignedPreKeyStores(this.attachedDatabase, [this._alias]); + late final GeneratedColumn signedPreKeyId = GeneratedColumn( + 'signed_pre_key_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn signedPreKey = + GeneratedColumn( + 'signed_pre_key', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [ + signedPreKeyId, + signedPreKey, + createdAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'signal_signed_pre_key_stores'; + @override + Set get $primaryKey => {signedPreKeyId}; + @override + SignalSignedPreKeyStoresData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return SignalSignedPreKeyStoresData( + signedPreKeyId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}signed_pre_key_id'], + )!, + signedPreKey: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}signed_pre_key'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + SignalSignedPreKeyStores createAlias(String alias) { + return SignalSignedPreKeyStores(attachedDatabase, alias); + } + + @override + List get customConstraints => const [ + 'PRIMARY KEY(signed_pre_key_id)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class SignalSignedPreKeyStoresData extends DataClass + implements Insertable { + final int signedPreKeyId; + final i2.Uint8List signedPreKey; + final int createdAt; + const SignalSignedPreKeyStoresData({ + required this.signedPreKeyId, + required this.signedPreKey, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['signed_pre_key_id'] = Variable(signedPreKeyId); + map['signed_pre_key'] = Variable(signedPreKey); + map['created_at'] = Variable(createdAt); + return map; + } + + SignalSignedPreKeyStoresCompanion toCompanion(bool nullToAbsent) { + return SignalSignedPreKeyStoresCompanion( + signedPreKeyId: Value(signedPreKeyId), + signedPreKey: Value(signedPreKey), + createdAt: Value(createdAt), + ); + } + + factory SignalSignedPreKeyStoresData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return SignalSignedPreKeyStoresData( + signedPreKeyId: serializer.fromJson(json['signedPreKeyId']), + signedPreKey: serializer.fromJson(json['signedPreKey']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'signedPreKeyId': serializer.toJson(signedPreKeyId), + 'signedPreKey': serializer.toJson(signedPreKey), + 'createdAt': serializer.toJson(createdAt), + }; + } + + SignalSignedPreKeyStoresData copyWith({ + int? signedPreKeyId, + i2.Uint8List? signedPreKey, + int? createdAt, + }) => SignalSignedPreKeyStoresData( + signedPreKeyId: signedPreKeyId ?? this.signedPreKeyId, + signedPreKey: signedPreKey ?? this.signedPreKey, + createdAt: createdAt ?? this.createdAt, + ); + SignalSignedPreKeyStoresData copyWithCompanion( + SignalSignedPreKeyStoresCompanion data, + ) { + return SignalSignedPreKeyStoresData( + signedPreKeyId: data.signedPreKeyId.present + ? data.signedPreKeyId.value + : this.signedPreKeyId, + signedPreKey: data.signedPreKey.present + ? data.signedPreKey.value + : this.signedPreKey, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('SignalSignedPreKeyStoresData(') + ..write('signedPreKeyId: $signedPreKeyId, ') + ..write('signedPreKey: $signedPreKey, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + signedPreKeyId, + $driftBlobEquality.hash(signedPreKey), + createdAt, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is SignalSignedPreKeyStoresData && + other.signedPreKeyId == this.signedPreKeyId && + $driftBlobEquality.equals(other.signedPreKey, this.signedPreKey) && + other.createdAt == this.createdAt); +} + +class SignalSignedPreKeyStoresCompanion + extends UpdateCompanion { + final Value signedPreKeyId; + final Value signedPreKey; + final Value createdAt; + const SignalSignedPreKeyStoresCompanion({ + this.signedPreKeyId = const Value.absent(), + this.signedPreKey = const Value.absent(), + this.createdAt = const Value.absent(), + }); + SignalSignedPreKeyStoresCompanion.insert({ + this.signedPreKeyId = const Value.absent(), + required i2.Uint8List signedPreKey, + this.createdAt = const Value.absent(), + }) : signedPreKey = Value(signedPreKey); + static Insertable custom({ + Expression? signedPreKeyId, + Expression? signedPreKey, + Expression? createdAt, + }) { + return RawValuesInsertable({ + if (signedPreKeyId != null) 'signed_pre_key_id': signedPreKeyId, + if (signedPreKey != null) 'signed_pre_key': signedPreKey, + if (createdAt != null) 'created_at': createdAt, + }); + } + + SignalSignedPreKeyStoresCompanion copyWith({ + Value? signedPreKeyId, + Value? signedPreKey, + Value? createdAt, + }) { + return SignalSignedPreKeyStoresCompanion( + signedPreKeyId: signedPreKeyId ?? this.signedPreKeyId, + signedPreKey: signedPreKey ?? this.signedPreKey, + createdAt: createdAt ?? this.createdAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (signedPreKeyId.present) { + map['signed_pre_key_id'] = Variable(signedPreKeyId.value); + } + if (signedPreKey.present) { + map['signed_pre_key'] = Variable(signedPreKey.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('SignalSignedPreKeyStoresCompanion(') + ..write('signedPreKeyId: $signedPreKeyId, ') + ..write('signedPreKey: $signedPreKey, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } +} + +class MessageActions extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + MessageActions(this.attachedDatabase, [this._alias]); + late final GeneratedColumn messageId = GeneratedColumn( + 'message_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES messages(message_id)ON DELETE CASCADE', + ); + late final GeneratedColumn contactId = GeneratedColumn( + 'contact_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES contacts(user_id)ON DELETE CASCADE', + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn actionAt = GeneratedColumn( + 'action_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [messageId, contactId, type, actionAt]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'message_actions'; + @override + Set get $primaryKey => {messageId, contactId, type}; + @override + MessageActionsData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return MessageActionsData( + messageId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}message_id'], + )!, + contactId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}contact_id'], + )!, + type: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}type'], + )!, + actionAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}action_at'], + )!, + ); + } + + @override + MessageActions createAlias(String alias) { + return MessageActions(attachedDatabase, alias); + } + + @override + List get customConstraints => const [ + 'PRIMARY KEY(message_id, contact_id, type)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class MessageActionsData extends DataClass + implements Insertable { + final String messageId; + final int contactId; + final String type; + final int actionAt; + const MessageActionsData({ + required this.messageId, + required this.contactId, + required this.type, + required this.actionAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['message_id'] = Variable(messageId); + map['contact_id'] = Variable(contactId); + map['type'] = Variable(type); + map['action_at'] = Variable(actionAt); + return map; + } + + MessageActionsCompanion toCompanion(bool nullToAbsent) { + return MessageActionsCompanion( + messageId: Value(messageId), + contactId: Value(contactId), + type: Value(type), + actionAt: Value(actionAt), + ); + } + + factory MessageActionsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return MessageActionsData( + messageId: serializer.fromJson(json['messageId']), + contactId: serializer.fromJson(json['contactId']), + type: serializer.fromJson(json['type']), + actionAt: serializer.fromJson(json['actionAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'messageId': serializer.toJson(messageId), + 'contactId': serializer.toJson(contactId), + 'type': serializer.toJson(type), + 'actionAt': serializer.toJson(actionAt), + }; + } + + MessageActionsData copyWith({ + String? messageId, + int? contactId, + String? type, + int? actionAt, + }) => MessageActionsData( + messageId: messageId ?? this.messageId, + contactId: contactId ?? this.contactId, + type: type ?? this.type, + actionAt: actionAt ?? this.actionAt, + ); + MessageActionsData copyWithCompanion(MessageActionsCompanion data) { + return MessageActionsData( + messageId: data.messageId.present ? data.messageId.value : this.messageId, + contactId: data.contactId.present ? data.contactId.value : this.contactId, + type: data.type.present ? data.type.value : this.type, + actionAt: data.actionAt.present ? data.actionAt.value : this.actionAt, + ); + } + + @override + String toString() { + return (StringBuffer('MessageActionsData(') + ..write('messageId: $messageId, ') + ..write('contactId: $contactId, ') + ..write('type: $type, ') + ..write('actionAt: $actionAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(messageId, contactId, type, actionAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is MessageActionsData && + other.messageId == this.messageId && + other.contactId == this.contactId && + other.type == this.type && + other.actionAt == this.actionAt); +} + +class MessageActionsCompanion extends UpdateCompanion { + final Value messageId; + final Value contactId; + final Value type; + final Value actionAt; + final Value rowid; + const MessageActionsCompanion({ + this.messageId = const Value.absent(), + this.contactId = const Value.absent(), + this.type = const Value.absent(), + this.actionAt = const Value.absent(), + this.rowid = const Value.absent(), + }); + MessageActionsCompanion.insert({ + required String messageId, + required int contactId, + required String type, + this.actionAt = const Value.absent(), + this.rowid = const Value.absent(), + }) : messageId = Value(messageId), + contactId = Value(contactId), + type = Value(type); + static Insertable custom({ + Expression? messageId, + Expression? contactId, + Expression? type, + Expression? actionAt, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (messageId != null) 'message_id': messageId, + if (contactId != null) 'contact_id': contactId, + if (type != null) 'type': type, + if (actionAt != null) 'action_at': actionAt, + if (rowid != null) 'rowid': rowid, + }); + } + + MessageActionsCompanion copyWith({ + Value? messageId, + Value? contactId, + Value? type, + Value? actionAt, + Value? rowid, + }) { + return MessageActionsCompanion( + messageId: messageId ?? this.messageId, + contactId: contactId ?? this.contactId, + type: type ?? this.type, + actionAt: actionAt ?? this.actionAt, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (messageId.present) { + map['message_id'] = Variable(messageId.value); + } + if (contactId.present) { + map['contact_id'] = Variable(contactId.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (actionAt.present) { + map['action_at'] = Variable(actionAt.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('MessageActionsCompanion(') + ..write('messageId: $messageId, ') + ..write('contactId: $contactId, ') + ..write('type: $type, ') + ..write('actionAt: $actionAt, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class GroupHistories extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + GroupHistories(this.attachedDatabase, [this._alias]); + late final GeneratedColumn groupHistoryId = GeneratedColumn( + 'group_history_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn groupId = GeneratedColumn( + 'group_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES "groups"(group_id)ON DELETE CASCADE', + ); + late final GeneratedColumn contactId = GeneratedColumn( + 'contact_id', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL REFERENCES contacts(user_id)', + ); + late final GeneratedColumn affectedContactId = GeneratedColumn( + 'affected_contact_id', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn oldGroupName = GeneratedColumn( + 'old_group_name', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn newGroupName = GeneratedColumn( + 'new_group_name', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn newDeleteMessagesAfterMilliseconds = + GeneratedColumn( + 'new_delete_messages_after_milliseconds', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn actionAt = GeneratedColumn( + 'action_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [ + groupHistoryId, + groupId, + contactId, + affectedContactId, + oldGroupName, + newGroupName, + newDeleteMessagesAfterMilliseconds, + type, + actionAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'group_histories'; + @override + Set get $primaryKey => {groupHistoryId}; + @override + GroupHistoriesData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return GroupHistoriesData( + groupHistoryId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}group_history_id'], + )!, + groupId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}group_id'], + )!, + contactId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}contact_id'], + ), + affectedContactId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}affected_contact_id'], + ), + oldGroupName: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}old_group_name'], + ), + newGroupName: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}new_group_name'], + ), + newDeleteMessagesAfterMilliseconds: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}new_delete_messages_after_milliseconds'], + ), + type: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}type'], + )!, + actionAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}action_at'], + )!, + ); + } + + @override + GroupHistories createAlias(String alias) { + return GroupHistories(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(group_history_id)']; + @override + bool get dontWriteConstraints => true; +} + +class GroupHistoriesData extends DataClass + implements Insertable { + final String groupHistoryId; + final String groupId; + final int? contactId; + final int? affectedContactId; + final String? oldGroupName; + final String? newGroupName; + final int? newDeleteMessagesAfterMilliseconds; + final String type; + final int actionAt; + const GroupHistoriesData({ + required this.groupHistoryId, + required this.groupId, + this.contactId, + this.affectedContactId, + this.oldGroupName, + this.newGroupName, + this.newDeleteMessagesAfterMilliseconds, + required this.type, + required this.actionAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['group_history_id'] = Variable(groupHistoryId); + map['group_id'] = Variable(groupId); + if (!nullToAbsent || contactId != null) { + map['contact_id'] = Variable(contactId); + } + if (!nullToAbsent || affectedContactId != null) { + map['affected_contact_id'] = Variable(affectedContactId); + } + if (!nullToAbsent || oldGroupName != null) { + map['old_group_name'] = Variable(oldGroupName); + } + if (!nullToAbsent || newGroupName != null) { + map['new_group_name'] = Variable(newGroupName); + } + if (!nullToAbsent || newDeleteMessagesAfterMilliseconds != null) { + map['new_delete_messages_after_milliseconds'] = Variable( + newDeleteMessagesAfterMilliseconds, + ); + } + map['type'] = Variable(type); + map['action_at'] = Variable(actionAt); + return map; + } + + GroupHistoriesCompanion toCompanion(bool nullToAbsent) { + return GroupHistoriesCompanion( + groupHistoryId: Value(groupHistoryId), + groupId: Value(groupId), + contactId: contactId == null && nullToAbsent + ? const Value.absent() + : Value(contactId), + affectedContactId: affectedContactId == null && nullToAbsent + ? const Value.absent() + : Value(affectedContactId), + oldGroupName: oldGroupName == null && nullToAbsent + ? const Value.absent() + : Value(oldGroupName), + newGroupName: newGroupName == null && nullToAbsent + ? const Value.absent() + : Value(newGroupName), + newDeleteMessagesAfterMilliseconds: + newDeleteMessagesAfterMilliseconds == null && nullToAbsent + ? const Value.absent() + : Value(newDeleteMessagesAfterMilliseconds), + type: Value(type), + actionAt: Value(actionAt), + ); + } + + factory GroupHistoriesData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return GroupHistoriesData( + groupHistoryId: serializer.fromJson(json['groupHistoryId']), + groupId: serializer.fromJson(json['groupId']), + contactId: serializer.fromJson(json['contactId']), + affectedContactId: serializer.fromJson(json['affectedContactId']), + oldGroupName: serializer.fromJson(json['oldGroupName']), + newGroupName: serializer.fromJson(json['newGroupName']), + newDeleteMessagesAfterMilliseconds: serializer.fromJson( + json['newDeleteMessagesAfterMilliseconds'], + ), + type: serializer.fromJson(json['type']), + actionAt: serializer.fromJson(json['actionAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'groupHistoryId': serializer.toJson(groupHistoryId), + 'groupId': serializer.toJson(groupId), + 'contactId': serializer.toJson(contactId), + 'affectedContactId': serializer.toJson(affectedContactId), + 'oldGroupName': serializer.toJson(oldGroupName), + 'newGroupName': serializer.toJson(newGroupName), + 'newDeleteMessagesAfterMilliseconds': serializer.toJson( + newDeleteMessagesAfterMilliseconds, + ), + 'type': serializer.toJson(type), + 'actionAt': serializer.toJson(actionAt), + }; + } + + GroupHistoriesData copyWith({ + String? groupHistoryId, + String? groupId, + Value contactId = const Value.absent(), + Value affectedContactId = const Value.absent(), + Value oldGroupName = const Value.absent(), + Value newGroupName = const Value.absent(), + Value newDeleteMessagesAfterMilliseconds = const Value.absent(), + String? type, + int? actionAt, + }) => GroupHistoriesData( + groupHistoryId: groupHistoryId ?? this.groupHistoryId, + groupId: groupId ?? this.groupId, + contactId: contactId.present ? contactId.value : this.contactId, + affectedContactId: affectedContactId.present + ? affectedContactId.value + : this.affectedContactId, + oldGroupName: oldGroupName.present ? oldGroupName.value : this.oldGroupName, + newGroupName: newGroupName.present ? newGroupName.value : this.newGroupName, + newDeleteMessagesAfterMilliseconds: + newDeleteMessagesAfterMilliseconds.present + ? newDeleteMessagesAfterMilliseconds.value + : this.newDeleteMessagesAfterMilliseconds, + type: type ?? this.type, + actionAt: actionAt ?? this.actionAt, + ); + GroupHistoriesData copyWithCompanion(GroupHistoriesCompanion data) { + return GroupHistoriesData( + groupHistoryId: data.groupHistoryId.present + ? data.groupHistoryId.value + : this.groupHistoryId, + groupId: data.groupId.present ? data.groupId.value : this.groupId, + contactId: data.contactId.present ? data.contactId.value : this.contactId, + affectedContactId: data.affectedContactId.present + ? data.affectedContactId.value + : this.affectedContactId, + oldGroupName: data.oldGroupName.present + ? data.oldGroupName.value + : this.oldGroupName, + newGroupName: data.newGroupName.present + ? data.newGroupName.value + : this.newGroupName, + newDeleteMessagesAfterMilliseconds: + data.newDeleteMessagesAfterMilliseconds.present + ? data.newDeleteMessagesAfterMilliseconds.value + : this.newDeleteMessagesAfterMilliseconds, + type: data.type.present ? data.type.value : this.type, + actionAt: data.actionAt.present ? data.actionAt.value : this.actionAt, + ); + } + + @override + String toString() { + return (StringBuffer('GroupHistoriesData(') + ..write('groupHistoryId: $groupHistoryId, ') + ..write('groupId: $groupId, ') + ..write('contactId: $contactId, ') + ..write('affectedContactId: $affectedContactId, ') + ..write('oldGroupName: $oldGroupName, ') + ..write('newGroupName: $newGroupName, ') + ..write( + 'newDeleteMessagesAfterMilliseconds: $newDeleteMessagesAfterMilliseconds, ', + ) + ..write('type: $type, ') + ..write('actionAt: $actionAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + groupHistoryId, + groupId, + contactId, + affectedContactId, + oldGroupName, + newGroupName, + newDeleteMessagesAfterMilliseconds, + type, + actionAt, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is GroupHistoriesData && + other.groupHistoryId == this.groupHistoryId && + other.groupId == this.groupId && + other.contactId == this.contactId && + other.affectedContactId == this.affectedContactId && + other.oldGroupName == this.oldGroupName && + other.newGroupName == this.newGroupName && + other.newDeleteMessagesAfterMilliseconds == + this.newDeleteMessagesAfterMilliseconds && + other.type == this.type && + other.actionAt == this.actionAt); +} + +class GroupHistoriesCompanion extends UpdateCompanion { + final Value groupHistoryId; + final Value groupId; + final Value contactId; + final Value affectedContactId; + final Value oldGroupName; + final Value newGroupName; + final Value newDeleteMessagesAfterMilliseconds; + final Value type; + final Value actionAt; + final Value rowid; + const GroupHistoriesCompanion({ + this.groupHistoryId = const Value.absent(), + this.groupId = const Value.absent(), + this.contactId = const Value.absent(), + this.affectedContactId = const Value.absent(), + this.oldGroupName = const Value.absent(), + this.newGroupName = const Value.absent(), + this.newDeleteMessagesAfterMilliseconds = const Value.absent(), + this.type = const Value.absent(), + this.actionAt = const Value.absent(), + this.rowid = const Value.absent(), + }); + GroupHistoriesCompanion.insert({ + required String groupHistoryId, + required String groupId, + this.contactId = const Value.absent(), + this.affectedContactId = const Value.absent(), + this.oldGroupName = const Value.absent(), + this.newGroupName = const Value.absent(), + this.newDeleteMessagesAfterMilliseconds = const Value.absent(), + required String type, + this.actionAt = const Value.absent(), + this.rowid = const Value.absent(), + }) : groupHistoryId = Value(groupHistoryId), + groupId = Value(groupId), + type = Value(type); + static Insertable custom({ + Expression? groupHistoryId, + Expression? groupId, + Expression? contactId, + Expression? affectedContactId, + Expression? oldGroupName, + Expression? newGroupName, + Expression? newDeleteMessagesAfterMilliseconds, + Expression? type, + Expression? actionAt, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (groupHistoryId != null) 'group_history_id': groupHistoryId, + if (groupId != null) 'group_id': groupId, + if (contactId != null) 'contact_id': contactId, + if (affectedContactId != null) 'affected_contact_id': affectedContactId, + if (oldGroupName != null) 'old_group_name': oldGroupName, + if (newGroupName != null) 'new_group_name': newGroupName, + if (newDeleteMessagesAfterMilliseconds != null) + 'new_delete_messages_after_milliseconds': + newDeleteMessagesAfterMilliseconds, + if (type != null) 'type': type, + if (actionAt != null) 'action_at': actionAt, + if (rowid != null) 'rowid': rowid, + }); + } + + GroupHistoriesCompanion copyWith({ + Value? groupHistoryId, + Value? groupId, + Value? contactId, + Value? affectedContactId, + Value? oldGroupName, + Value? newGroupName, + Value? newDeleteMessagesAfterMilliseconds, + Value? type, + Value? actionAt, + Value? rowid, + }) { + return GroupHistoriesCompanion( + groupHistoryId: groupHistoryId ?? this.groupHistoryId, + groupId: groupId ?? this.groupId, + contactId: contactId ?? this.contactId, + affectedContactId: affectedContactId ?? this.affectedContactId, + oldGroupName: oldGroupName ?? this.oldGroupName, + newGroupName: newGroupName ?? this.newGroupName, + newDeleteMessagesAfterMilliseconds: + newDeleteMessagesAfterMilliseconds ?? + this.newDeleteMessagesAfterMilliseconds, + type: type ?? this.type, + actionAt: actionAt ?? this.actionAt, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (groupHistoryId.present) { + map['group_history_id'] = Variable(groupHistoryId.value); + } + if (groupId.present) { + map['group_id'] = Variable(groupId.value); + } + if (contactId.present) { + map['contact_id'] = Variable(contactId.value); + } + if (affectedContactId.present) { + map['affected_contact_id'] = Variable(affectedContactId.value); + } + if (oldGroupName.present) { + map['old_group_name'] = Variable(oldGroupName.value); + } + if (newGroupName.present) { + map['new_group_name'] = Variable(newGroupName.value); + } + if (newDeleteMessagesAfterMilliseconds.present) { + map['new_delete_messages_after_milliseconds'] = Variable( + newDeleteMessagesAfterMilliseconds.value, + ); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (actionAt.present) { + map['action_at'] = Variable(actionAt.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('GroupHistoriesCompanion(') + ..write('groupHistoryId: $groupHistoryId, ') + ..write('groupId: $groupId, ') + ..write('contactId: $contactId, ') + ..write('affectedContactId: $affectedContactId, ') + ..write('oldGroupName: $oldGroupName, ') + ..write('newGroupName: $newGroupName, ') + ..write( + 'newDeleteMessagesAfterMilliseconds: $newDeleteMessagesAfterMilliseconds, ', + ) + ..write('type: $type, ') + ..write('actionAt: $actionAt, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class KeyVerifications extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + KeyVerifications(this.attachedDatabase, [this._alias]); + late final GeneratedColumn verificationId = GeneratedColumn( + 'verification_id', + aliasedName, + false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL PRIMARY KEY AUTOINCREMENT', + ); + late final GeneratedColumn contactId = GeneratedColumn( + 'contact_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES contacts(user_id)ON DELETE CASCADE', + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn verifiedBy = GeneratedColumn( + 'verified_by', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL REFERENCES contacts(user_id)ON DELETE CASCADE', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [ + verificationId, + contactId, + type, + verifiedBy, + createdAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'key_verifications'; + @override + Set get $primaryKey => {verificationId}; + @override + KeyVerificationsData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return KeyVerificationsData( + verificationId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}verification_id'], + )!, + contactId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}contact_id'], + )!, + type: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}type'], + )!, + verifiedBy: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}verified_by'], + ), + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + KeyVerifications createAlias(String alias) { + return KeyVerifications(attachedDatabase, alias); + } + + @override + bool get dontWriteConstraints => true; +} + +class KeyVerificationsData extends DataClass + implements Insertable { + final int verificationId; + final int contactId; + final String type; + final int? verifiedBy; + final int createdAt; + const KeyVerificationsData({ + required this.verificationId, + required this.contactId, + required this.type, + this.verifiedBy, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['verification_id'] = Variable(verificationId); + map['contact_id'] = Variable(contactId); + map['type'] = Variable(type); + if (!nullToAbsent || verifiedBy != null) { + map['verified_by'] = Variable(verifiedBy); + } + map['created_at'] = Variable(createdAt); + return map; + } + + KeyVerificationsCompanion toCompanion(bool nullToAbsent) { + return KeyVerificationsCompanion( + verificationId: Value(verificationId), + contactId: Value(contactId), + type: Value(type), + verifiedBy: verifiedBy == null && nullToAbsent + ? const Value.absent() + : Value(verifiedBy), + createdAt: Value(createdAt), + ); + } + + factory KeyVerificationsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return KeyVerificationsData( + verificationId: serializer.fromJson(json['verificationId']), + contactId: serializer.fromJson(json['contactId']), + type: serializer.fromJson(json['type']), + verifiedBy: serializer.fromJson(json['verifiedBy']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'verificationId': serializer.toJson(verificationId), + 'contactId': serializer.toJson(contactId), + 'type': serializer.toJson(type), + 'verifiedBy': serializer.toJson(verifiedBy), + 'createdAt': serializer.toJson(createdAt), + }; + } + + KeyVerificationsData copyWith({ + int? verificationId, + int? contactId, + String? type, + Value verifiedBy = const Value.absent(), + int? createdAt, + }) => KeyVerificationsData( + verificationId: verificationId ?? this.verificationId, + contactId: contactId ?? this.contactId, + type: type ?? this.type, + verifiedBy: verifiedBy.present ? verifiedBy.value : this.verifiedBy, + createdAt: createdAt ?? this.createdAt, + ); + KeyVerificationsData copyWithCompanion(KeyVerificationsCompanion data) { + return KeyVerificationsData( + verificationId: data.verificationId.present + ? data.verificationId.value + : this.verificationId, + contactId: data.contactId.present ? data.contactId.value : this.contactId, + type: data.type.present ? data.type.value : this.type, + verifiedBy: data.verifiedBy.present + ? data.verifiedBy.value + : this.verifiedBy, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('KeyVerificationsData(') + ..write('verificationId: $verificationId, ') + ..write('contactId: $contactId, ') + ..write('type: $type, ') + ..write('verifiedBy: $verifiedBy, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => + Object.hash(verificationId, contactId, type, verifiedBy, createdAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is KeyVerificationsData && + other.verificationId == this.verificationId && + other.contactId == this.contactId && + other.type == this.type && + other.verifiedBy == this.verifiedBy && + other.createdAt == this.createdAt); +} + +class KeyVerificationsCompanion extends UpdateCompanion { + final Value verificationId; + final Value contactId; + final Value type; + final Value verifiedBy; + final Value createdAt; + const KeyVerificationsCompanion({ + this.verificationId = const Value.absent(), + this.contactId = const Value.absent(), + this.type = const Value.absent(), + this.verifiedBy = const Value.absent(), + this.createdAt = const Value.absent(), + }); + KeyVerificationsCompanion.insert({ + this.verificationId = const Value.absent(), + required int contactId, + required String type, + this.verifiedBy = const Value.absent(), + this.createdAt = const Value.absent(), + }) : contactId = Value(contactId), + type = Value(type); + static Insertable custom({ + Expression? verificationId, + Expression? contactId, + Expression? type, + Expression? verifiedBy, + Expression? createdAt, + }) { + return RawValuesInsertable({ + if (verificationId != null) 'verification_id': verificationId, + if (contactId != null) 'contact_id': contactId, + if (type != null) 'type': type, + if (verifiedBy != null) 'verified_by': verifiedBy, + if (createdAt != null) 'created_at': createdAt, + }); + } + + KeyVerificationsCompanion copyWith({ + Value? verificationId, + Value? contactId, + Value? type, + Value? verifiedBy, + Value? createdAt, + }) { + return KeyVerificationsCompanion( + verificationId: verificationId ?? this.verificationId, + contactId: contactId ?? this.contactId, + type: type ?? this.type, + verifiedBy: verifiedBy ?? this.verifiedBy, + createdAt: createdAt ?? this.createdAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (verificationId.present) { + map['verification_id'] = Variable(verificationId.value); + } + if (contactId.present) { + map['contact_id'] = Variable(contactId.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (verifiedBy.present) { + map['verified_by'] = Variable(verifiedBy.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('KeyVerificationsCompanion(') + ..write('verificationId: $verificationId, ') + ..write('contactId: $contactId, ') + ..write('type: $type, ') + ..write('verifiedBy: $verifiedBy, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } +} + +class VerificationTokens extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + VerificationTokens(this.attachedDatabase, [this._alias]); + late final GeneratedColumn tokenId = GeneratedColumn( + 'token_id', + aliasedName, + false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL PRIMARY KEY AUTOINCREMENT', + ); + late final GeneratedColumn token = + GeneratedColumn( + 'token', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [tokenId, token, createdAt]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'verification_tokens'; + @override + Set get $primaryKey => {tokenId}; + @override + VerificationTokensData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return VerificationTokensData( + tokenId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}token_id'], + )!, + token: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}token'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + VerificationTokens createAlias(String alias) { + return VerificationTokens(attachedDatabase, alias); + } + + @override + bool get dontWriteConstraints => true; +} + +class VerificationTokensData extends DataClass + implements Insertable { + final int tokenId; + final i2.Uint8List token; + final int createdAt; + const VerificationTokensData({ + required this.tokenId, + required this.token, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['token_id'] = Variable(tokenId); + map['token'] = Variable(token); + map['created_at'] = Variable(createdAt); + return map; + } + + VerificationTokensCompanion toCompanion(bool nullToAbsent) { + return VerificationTokensCompanion( + tokenId: Value(tokenId), + token: Value(token), + createdAt: Value(createdAt), + ); + } + + factory VerificationTokensData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return VerificationTokensData( + tokenId: serializer.fromJson(json['tokenId']), + token: serializer.fromJson(json['token']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'tokenId': serializer.toJson(tokenId), + 'token': serializer.toJson(token), + 'createdAt': serializer.toJson(createdAt), + }; + } + + VerificationTokensData copyWith({ + int? tokenId, + i2.Uint8List? token, + int? createdAt, + }) => VerificationTokensData( + tokenId: tokenId ?? this.tokenId, + token: token ?? this.token, + createdAt: createdAt ?? this.createdAt, + ); + VerificationTokensData copyWithCompanion(VerificationTokensCompanion data) { + return VerificationTokensData( + tokenId: data.tokenId.present ? data.tokenId.value : this.tokenId, + token: data.token.present ? data.token.value : this.token, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('VerificationTokensData(') + ..write('tokenId: $tokenId, ') + ..write('token: $token, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => + Object.hash(tokenId, $driftBlobEquality.hash(token), createdAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is VerificationTokensData && + other.tokenId == this.tokenId && + $driftBlobEquality.equals(other.token, this.token) && + other.createdAt == this.createdAt); +} + +class VerificationTokensCompanion + extends UpdateCompanion { + final Value tokenId; + final Value token; + final Value createdAt; + const VerificationTokensCompanion({ + this.tokenId = const Value.absent(), + this.token = const Value.absent(), + this.createdAt = const Value.absent(), + }); + VerificationTokensCompanion.insert({ + this.tokenId = const Value.absent(), + required i2.Uint8List token, + this.createdAt = const Value.absent(), + }) : token = Value(token); + static Insertable custom({ + Expression? tokenId, + Expression? token, + Expression? createdAt, + }) { + return RawValuesInsertable({ + if (tokenId != null) 'token_id': tokenId, + if (token != null) 'token': token, + if (createdAt != null) 'created_at': createdAt, + }); + } + + VerificationTokensCompanion copyWith({ + Value? tokenId, + Value? token, + Value? createdAt, + }) { + return VerificationTokensCompanion( + tokenId: tokenId ?? this.tokenId, + token: token ?? this.token, + createdAt: createdAt ?? this.createdAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (tokenId.present) { + map['token_id'] = Variable(tokenId.value); + } + if (token.present) { + map['token'] = Variable(token.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('VerificationTokensCompanion(') + ..write('tokenId: $tokenId, ') + ..write('token: $token, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } +} + +class UserDiscoveryAnnouncedUsers extends Table + with + TableInfo< + UserDiscoveryAnnouncedUsers, + UserDiscoveryAnnouncedUsersData + > { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + UserDiscoveryAnnouncedUsers(this.attachedDatabase, [this._alias]); + late final GeneratedColumn announcedUserId = GeneratedColumn( + 'announced_user_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn announcedPublicKey = + GeneratedColumn( + 'announced_public_key', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn publicId = GeneratedColumn( + 'public_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL UNIQUE', + ); + late final GeneratedColumn username = GeneratedColumn( + 'username', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn wasShownToTheUser = GeneratedColumn( + 'was_shown_to_the_user', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 CHECK (was_shown_to_the_user IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn isHidden = GeneratedColumn( + 'is_hidden', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_hidden IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn wasAskedFriends = GeneratedColumn( + 'was_asked_friends', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 CHECK (was_asked_friends IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [ + announcedUserId, + announcedPublicKey, + publicId, + username, + wasShownToTheUser, + isHidden, + wasAskedFriends, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'user_discovery_announced_users'; + @override + Set get $primaryKey => {announcedUserId}; + @override + UserDiscoveryAnnouncedUsersData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return UserDiscoveryAnnouncedUsersData( + announcedUserId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}announced_user_id'], + )!, + announcedPublicKey: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}announced_public_key'], + )!, + publicId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}public_id'], + )!, + username: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}username'], + ), + wasShownToTheUser: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}was_shown_to_the_user'], + )!, + isHidden: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_hidden'], + )!, + wasAskedFriends: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}was_asked_friends'], + )!, + ); + } + + @override + UserDiscoveryAnnouncedUsers createAlias(String alias) { + return UserDiscoveryAnnouncedUsers(attachedDatabase, alias); + } + + @override + List get customConstraints => const [ + 'PRIMARY KEY(announced_user_id)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class UserDiscoveryAnnouncedUsersData extends DataClass + implements Insertable { + final int announcedUserId; + final i2.Uint8List announcedPublicKey; + final int publicId; + final String? username; + final int wasShownToTheUser; + final int isHidden; + final int wasAskedFriends; + const UserDiscoveryAnnouncedUsersData({ + required this.announcedUserId, + required this.announcedPublicKey, + required this.publicId, + this.username, + required this.wasShownToTheUser, + required this.isHidden, + required this.wasAskedFriends, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['announced_user_id'] = Variable(announcedUserId); + map['announced_public_key'] = Variable(announcedPublicKey); + map['public_id'] = Variable(publicId); + if (!nullToAbsent || username != null) { + map['username'] = Variable(username); + } + map['was_shown_to_the_user'] = Variable(wasShownToTheUser); + map['is_hidden'] = Variable(isHidden); + map['was_asked_friends'] = Variable(wasAskedFriends); + return map; + } + + UserDiscoveryAnnouncedUsersCompanion toCompanion(bool nullToAbsent) { + return UserDiscoveryAnnouncedUsersCompanion( + announcedUserId: Value(announcedUserId), + announcedPublicKey: Value(announcedPublicKey), + publicId: Value(publicId), + username: username == null && nullToAbsent + ? const Value.absent() + : Value(username), + wasShownToTheUser: Value(wasShownToTheUser), + isHidden: Value(isHidden), + wasAskedFriends: Value(wasAskedFriends), + ); + } + + factory UserDiscoveryAnnouncedUsersData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UserDiscoveryAnnouncedUsersData( + announcedUserId: serializer.fromJson(json['announcedUserId']), + announcedPublicKey: serializer.fromJson( + json['announcedPublicKey'], + ), + publicId: serializer.fromJson(json['publicId']), + username: serializer.fromJson(json['username']), + wasShownToTheUser: serializer.fromJson(json['wasShownToTheUser']), + isHidden: serializer.fromJson(json['isHidden']), + wasAskedFriends: serializer.fromJson(json['wasAskedFriends']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'announcedUserId': serializer.toJson(announcedUserId), + 'announcedPublicKey': serializer.toJson(announcedPublicKey), + 'publicId': serializer.toJson(publicId), + 'username': serializer.toJson(username), + 'wasShownToTheUser': serializer.toJson(wasShownToTheUser), + 'isHidden': serializer.toJson(isHidden), + 'wasAskedFriends': serializer.toJson(wasAskedFriends), + }; + } + + UserDiscoveryAnnouncedUsersData copyWith({ + int? announcedUserId, + i2.Uint8List? announcedPublicKey, + int? publicId, + Value username = const Value.absent(), + int? wasShownToTheUser, + int? isHidden, + int? wasAskedFriends, + }) => UserDiscoveryAnnouncedUsersData( + announcedUserId: announcedUserId ?? this.announcedUserId, + announcedPublicKey: announcedPublicKey ?? this.announcedPublicKey, + publicId: publicId ?? this.publicId, + username: username.present ? username.value : this.username, + wasShownToTheUser: wasShownToTheUser ?? this.wasShownToTheUser, + isHidden: isHidden ?? this.isHidden, + wasAskedFriends: wasAskedFriends ?? this.wasAskedFriends, + ); + UserDiscoveryAnnouncedUsersData copyWithCompanion( + UserDiscoveryAnnouncedUsersCompanion data, + ) { + return UserDiscoveryAnnouncedUsersData( + announcedUserId: data.announcedUserId.present + ? data.announcedUserId.value + : this.announcedUserId, + announcedPublicKey: data.announcedPublicKey.present + ? data.announcedPublicKey.value + : this.announcedPublicKey, + publicId: data.publicId.present ? data.publicId.value : this.publicId, + username: data.username.present ? data.username.value : this.username, + wasShownToTheUser: data.wasShownToTheUser.present + ? data.wasShownToTheUser.value + : this.wasShownToTheUser, + isHidden: data.isHidden.present ? data.isHidden.value : this.isHidden, + wasAskedFriends: data.wasAskedFriends.present + ? data.wasAskedFriends.value + : this.wasAskedFriends, + ); + } + + @override + String toString() { + return (StringBuffer('UserDiscoveryAnnouncedUsersData(') + ..write('announcedUserId: $announcedUserId, ') + ..write('announcedPublicKey: $announcedPublicKey, ') + ..write('publicId: $publicId, ') + ..write('username: $username, ') + ..write('wasShownToTheUser: $wasShownToTheUser, ') + ..write('isHidden: $isHidden, ') + ..write('wasAskedFriends: $wasAskedFriends') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + announcedUserId, + $driftBlobEquality.hash(announcedPublicKey), + publicId, + username, + wasShownToTheUser, + isHidden, + wasAskedFriends, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is UserDiscoveryAnnouncedUsersData && + other.announcedUserId == this.announcedUserId && + $driftBlobEquality.equals( + other.announcedPublicKey, + this.announcedPublicKey, + ) && + other.publicId == this.publicId && + other.username == this.username && + other.wasShownToTheUser == this.wasShownToTheUser && + other.isHidden == this.isHidden && + other.wasAskedFriends == this.wasAskedFriends); +} + +class UserDiscoveryAnnouncedUsersCompanion + extends UpdateCompanion { + final Value announcedUserId; + final Value announcedPublicKey; + final Value publicId; + final Value username; + final Value wasShownToTheUser; + final Value isHidden; + final Value wasAskedFriends; + const UserDiscoveryAnnouncedUsersCompanion({ + this.announcedUserId = const Value.absent(), + this.announcedPublicKey = const Value.absent(), + this.publicId = const Value.absent(), + this.username = const Value.absent(), + this.wasShownToTheUser = const Value.absent(), + this.isHidden = const Value.absent(), + this.wasAskedFriends = const Value.absent(), + }); + UserDiscoveryAnnouncedUsersCompanion.insert({ + this.announcedUserId = const Value.absent(), + required i2.Uint8List announcedPublicKey, + required int publicId, + this.username = const Value.absent(), + this.wasShownToTheUser = const Value.absent(), + this.isHidden = const Value.absent(), + this.wasAskedFriends = const Value.absent(), + }) : announcedPublicKey = Value(announcedPublicKey), + publicId = Value(publicId); + static Insertable custom({ + Expression? announcedUserId, + Expression? announcedPublicKey, + Expression? publicId, + Expression? username, + Expression? wasShownToTheUser, + Expression? isHidden, + Expression? wasAskedFriends, + }) { + return RawValuesInsertable({ + if (announcedUserId != null) 'announced_user_id': announcedUserId, + if (announcedPublicKey != null) + 'announced_public_key': announcedPublicKey, + if (publicId != null) 'public_id': publicId, + if (username != null) 'username': username, + if (wasShownToTheUser != null) 'was_shown_to_the_user': wasShownToTheUser, + if (isHidden != null) 'is_hidden': isHidden, + if (wasAskedFriends != null) 'was_asked_friends': wasAskedFriends, + }); + } + + UserDiscoveryAnnouncedUsersCompanion copyWith({ + Value? announcedUserId, + Value? announcedPublicKey, + Value? publicId, + Value? username, + Value? wasShownToTheUser, + Value? isHidden, + Value? wasAskedFriends, + }) { + return UserDiscoveryAnnouncedUsersCompanion( + announcedUserId: announcedUserId ?? this.announcedUserId, + announcedPublicKey: announcedPublicKey ?? this.announcedPublicKey, + publicId: publicId ?? this.publicId, + username: username ?? this.username, + wasShownToTheUser: wasShownToTheUser ?? this.wasShownToTheUser, + isHidden: isHidden ?? this.isHidden, + wasAskedFriends: wasAskedFriends ?? this.wasAskedFriends, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (announcedUserId.present) { + map['announced_user_id'] = Variable(announcedUserId.value); + } + if (announcedPublicKey.present) { + map['announced_public_key'] = Variable( + announcedPublicKey.value, + ); + } + if (publicId.present) { + map['public_id'] = Variable(publicId.value); + } + if (username.present) { + map['username'] = Variable(username.value); + } + if (wasShownToTheUser.present) { + map['was_shown_to_the_user'] = Variable(wasShownToTheUser.value); + } + if (isHidden.present) { + map['is_hidden'] = Variable(isHidden.value); + } + if (wasAskedFriends.present) { + map['was_asked_friends'] = Variable(wasAskedFriends.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('UserDiscoveryAnnouncedUsersCompanion(') + ..write('announcedUserId: $announcedUserId, ') + ..write('announcedPublicKey: $announcedPublicKey, ') + ..write('publicId: $publicId, ') + ..write('username: $username, ') + ..write('wasShownToTheUser: $wasShownToTheUser, ') + ..write('isHidden: $isHidden, ') + ..write('wasAskedFriends: $wasAskedFriends') + ..write(')')) + .toString(); + } +} + +class UserDiscoveryUserRelations extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + UserDiscoveryUserRelations(this.attachedDatabase, [this._alias]); + late final GeneratedColumn announcedUserId = GeneratedColumn( + 'announced_user_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES user_discovery_announced_users(announced_user_id)ON DELETE CASCADE', + ); + late final GeneratedColumn fromContactId = GeneratedColumn( + 'from_contact_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES contacts(user_id)ON DELETE CASCADE', + ); + late final GeneratedColumn publicKeyVerifiedTimestamp = + GeneratedColumn( + 'public_key_verified_timestamp', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + @override + List get $columns => [ + announcedUserId, + fromContactId, + publicKeyVerifiedTimestamp, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'user_discovery_user_relations'; + @override + Set get $primaryKey => {announcedUserId, fromContactId}; + @override + UserDiscoveryUserRelationsData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return UserDiscoveryUserRelationsData( + announcedUserId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}announced_user_id'], + )!, + fromContactId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}from_contact_id'], + )!, + publicKeyVerifiedTimestamp: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}public_key_verified_timestamp'], + ), + ); + } + + @override + UserDiscoveryUserRelations createAlias(String alias) { + return UserDiscoveryUserRelations(attachedDatabase, alias); + } + + @override + List get customConstraints => const [ + 'PRIMARY KEY(announced_user_id, from_contact_id)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class UserDiscoveryUserRelationsData extends DataClass + implements Insertable { + final int announcedUserId; + final int fromContactId; + final int? publicKeyVerifiedTimestamp; + const UserDiscoveryUserRelationsData({ + required this.announcedUserId, + required this.fromContactId, + this.publicKeyVerifiedTimestamp, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['announced_user_id'] = Variable(announcedUserId); + map['from_contact_id'] = Variable(fromContactId); + if (!nullToAbsent || publicKeyVerifiedTimestamp != null) { + map['public_key_verified_timestamp'] = Variable( + publicKeyVerifiedTimestamp, + ); + } + return map; + } + + UserDiscoveryUserRelationsCompanion toCompanion(bool nullToAbsent) { + return UserDiscoveryUserRelationsCompanion( + announcedUserId: Value(announcedUserId), + fromContactId: Value(fromContactId), + publicKeyVerifiedTimestamp: + publicKeyVerifiedTimestamp == null && nullToAbsent + ? const Value.absent() + : Value(publicKeyVerifiedTimestamp), + ); + } + + factory UserDiscoveryUserRelationsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UserDiscoveryUserRelationsData( + announcedUserId: serializer.fromJson(json['announcedUserId']), + fromContactId: serializer.fromJson(json['fromContactId']), + publicKeyVerifiedTimestamp: serializer.fromJson( + json['publicKeyVerifiedTimestamp'], + ), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'announcedUserId': serializer.toJson(announcedUserId), + 'fromContactId': serializer.toJson(fromContactId), + 'publicKeyVerifiedTimestamp': serializer.toJson( + publicKeyVerifiedTimestamp, + ), + }; + } + + UserDiscoveryUserRelationsData copyWith({ + int? announcedUserId, + int? fromContactId, + Value publicKeyVerifiedTimestamp = const Value.absent(), + }) => UserDiscoveryUserRelationsData( + announcedUserId: announcedUserId ?? this.announcedUserId, + fromContactId: fromContactId ?? this.fromContactId, + publicKeyVerifiedTimestamp: publicKeyVerifiedTimestamp.present + ? publicKeyVerifiedTimestamp.value + : this.publicKeyVerifiedTimestamp, + ); + UserDiscoveryUserRelationsData copyWithCompanion( + UserDiscoveryUserRelationsCompanion data, + ) { + return UserDiscoveryUserRelationsData( + announcedUserId: data.announcedUserId.present + ? data.announcedUserId.value + : this.announcedUserId, + fromContactId: data.fromContactId.present + ? data.fromContactId.value + : this.fromContactId, + publicKeyVerifiedTimestamp: data.publicKeyVerifiedTimestamp.present + ? data.publicKeyVerifiedTimestamp.value + : this.publicKeyVerifiedTimestamp, + ); + } + + @override + String toString() { + return (StringBuffer('UserDiscoveryUserRelationsData(') + ..write('announcedUserId: $announcedUserId, ') + ..write('fromContactId: $fromContactId, ') + ..write('publicKeyVerifiedTimestamp: $publicKeyVerifiedTimestamp') + ..write(')')) + .toString(); + } + + @override + int get hashCode => + Object.hash(announcedUserId, fromContactId, publicKeyVerifiedTimestamp); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is UserDiscoveryUserRelationsData && + other.announcedUserId == this.announcedUserId && + other.fromContactId == this.fromContactId && + other.publicKeyVerifiedTimestamp == this.publicKeyVerifiedTimestamp); +} + +class UserDiscoveryUserRelationsCompanion + extends UpdateCompanion { + final Value announcedUserId; + final Value fromContactId; + final Value publicKeyVerifiedTimestamp; + final Value rowid; + const UserDiscoveryUserRelationsCompanion({ + this.announcedUserId = const Value.absent(), + this.fromContactId = const Value.absent(), + this.publicKeyVerifiedTimestamp = const Value.absent(), + this.rowid = const Value.absent(), + }); + UserDiscoveryUserRelationsCompanion.insert({ + required int announcedUserId, + required int fromContactId, + this.publicKeyVerifiedTimestamp = const Value.absent(), + this.rowid = const Value.absent(), + }) : announcedUserId = Value(announcedUserId), + fromContactId = Value(fromContactId); + static Insertable custom({ + Expression? announcedUserId, + Expression? fromContactId, + Expression? publicKeyVerifiedTimestamp, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (announcedUserId != null) 'announced_user_id': announcedUserId, + if (fromContactId != null) 'from_contact_id': fromContactId, + if (publicKeyVerifiedTimestamp != null) + 'public_key_verified_timestamp': publicKeyVerifiedTimestamp, + if (rowid != null) 'rowid': rowid, + }); + } + + UserDiscoveryUserRelationsCompanion copyWith({ + Value? announcedUserId, + Value? fromContactId, + Value? publicKeyVerifiedTimestamp, + Value? rowid, + }) { + return UserDiscoveryUserRelationsCompanion( + announcedUserId: announcedUserId ?? this.announcedUserId, + fromContactId: fromContactId ?? this.fromContactId, + publicKeyVerifiedTimestamp: + publicKeyVerifiedTimestamp ?? this.publicKeyVerifiedTimestamp, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (announcedUserId.present) { + map['announced_user_id'] = Variable(announcedUserId.value); + } + if (fromContactId.present) { + map['from_contact_id'] = Variable(fromContactId.value); + } + if (publicKeyVerifiedTimestamp.present) { + map['public_key_verified_timestamp'] = Variable( + publicKeyVerifiedTimestamp.value, + ); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('UserDiscoveryUserRelationsCompanion(') + ..write('announcedUserId: $announcedUserId, ') + ..write('fromContactId: $fromContactId, ') + ..write('publicKeyVerifiedTimestamp: $publicKeyVerifiedTimestamp, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class UserDiscoveryOtherPromotions extends Table + with + TableInfo< + UserDiscoveryOtherPromotions, + UserDiscoveryOtherPromotionsData + > { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + UserDiscoveryOtherPromotions(this.attachedDatabase, [this._alias]); + late final GeneratedColumn fromContactId = GeneratedColumn( + 'from_contact_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES contacts(user_id)ON DELETE CASCADE', + ); + late final GeneratedColumn promotionId = GeneratedColumn( + 'promotion_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn publicId = GeneratedColumn( + 'public_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn threshold = GeneratedColumn( + 'threshold', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn announcementShare = + GeneratedColumn( + 'announcement_share', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn publicKeyVerifiedTimestamp = + GeneratedColumn( + 'public_key_verified_timestamp', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + @override + List get $columns => [ + fromContactId, + promotionId, + publicId, + threshold, + announcementShare, + publicKeyVerifiedTimestamp, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'user_discovery_other_promotions'; + @override + Set get $primaryKey => {fromContactId, publicId}; + @override + UserDiscoveryOtherPromotionsData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return UserDiscoveryOtherPromotionsData( + fromContactId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}from_contact_id'], + )!, + promotionId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}promotion_id'], + )!, + publicId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}public_id'], + )!, + threshold: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}threshold'], + )!, + announcementShare: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}announcement_share'], + )!, + publicKeyVerifiedTimestamp: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}public_key_verified_timestamp'], + ), + ); + } + + @override + UserDiscoveryOtherPromotions createAlias(String alias) { + return UserDiscoveryOtherPromotions(attachedDatabase, alias); + } + + @override + List get customConstraints => const [ + 'PRIMARY KEY(from_contact_id, public_id)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class UserDiscoveryOtherPromotionsData extends DataClass + implements Insertable { + final int fromContactId; + final int promotionId; + final int publicId; + final int threshold; + final i2.Uint8List announcementShare; + final int? publicKeyVerifiedTimestamp; + const UserDiscoveryOtherPromotionsData({ + required this.fromContactId, + required this.promotionId, + required this.publicId, + required this.threshold, + required this.announcementShare, + this.publicKeyVerifiedTimestamp, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['from_contact_id'] = Variable(fromContactId); + map['promotion_id'] = Variable(promotionId); + map['public_id'] = Variable(publicId); + map['threshold'] = Variable(threshold); + map['announcement_share'] = Variable(announcementShare); + if (!nullToAbsent || publicKeyVerifiedTimestamp != null) { + map['public_key_verified_timestamp'] = Variable( + publicKeyVerifiedTimestamp, + ); + } + return map; + } + + UserDiscoveryOtherPromotionsCompanion toCompanion(bool nullToAbsent) { + return UserDiscoveryOtherPromotionsCompanion( + fromContactId: Value(fromContactId), + promotionId: Value(promotionId), + publicId: Value(publicId), + threshold: Value(threshold), + announcementShare: Value(announcementShare), + publicKeyVerifiedTimestamp: + publicKeyVerifiedTimestamp == null && nullToAbsent + ? const Value.absent() + : Value(publicKeyVerifiedTimestamp), + ); + } + + factory UserDiscoveryOtherPromotionsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UserDiscoveryOtherPromotionsData( + fromContactId: serializer.fromJson(json['fromContactId']), + promotionId: serializer.fromJson(json['promotionId']), + publicId: serializer.fromJson(json['publicId']), + threshold: serializer.fromJson(json['threshold']), + announcementShare: serializer.fromJson( + json['announcementShare'], + ), + publicKeyVerifiedTimestamp: serializer.fromJson( + json['publicKeyVerifiedTimestamp'], + ), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'fromContactId': serializer.toJson(fromContactId), + 'promotionId': serializer.toJson(promotionId), + 'publicId': serializer.toJson(publicId), + 'threshold': serializer.toJson(threshold), + 'announcementShare': serializer.toJson(announcementShare), + 'publicKeyVerifiedTimestamp': serializer.toJson( + publicKeyVerifiedTimestamp, + ), + }; + } + + UserDiscoveryOtherPromotionsData copyWith({ + int? fromContactId, + int? promotionId, + int? publicId, + int? threshold, + i2.Uint8List? announcementShare, + Value publicKeyVerifiedTimestamp = const Value.absent(), + }) => UserDiscoveryOtherPromotionsData( + fromContactId: fromContactId ?? this.fromContactId, + promotionId: promotionId ?? this.promotionId, + publicId: publicId ?? this.publicId, + threshold: threshold ?? this.threshold, + announcementShare: announcementShare ?? this.announcementShare, + publicKeyVerifiedTimestamp: publicKeyVerifiedTimestamp.present + ? publicKeyVerifiedTimestamp.value + : this.publicKeyVerifiedTimestamp, + ); + UserDiscoveryOtherPromotionsData copyWithCompanion( + UserDiscoveryOtherPromotionsCompanion data, + ) { + return UserDiscoveryOtherPromotionsData( + fromContactId: data.fromContactId.present + ? data.fromContactId.value + : this.fromContactId, + promotionId: data.promotionId.present + ? data.promotionId.value + : this.promotionId, + publicId: data.publicId.present ? data.publicId.value : this.publicId, + threshold: data.threshold.present ? data.threshold.value : this.threshold, + announcementShare: data.announcementShare.present + ? data.announcementShare.value + : this.announcementShare, + publicKeyVerifiedTimestamp: data.publicKeyVerifiedTimestamp.present + ? data.publicKeyVerifiedTimestamp.value + : this.publicKeyVerifiedTimestamp, + ); + } + + @override + String toString() { + return (StringBuffer('UserDiscoveryOtherPromotionsData(') + ..write('fromContactId: $fromContactId, ') + ..write('promotionId: $promotionId, ') + ..write('publicId: $publicId, ') + ..write('threshold: $threshold, ') + ..write('announcementShare: $announcementShare, ') + ..write('publicKeyVerifiedTimestamp: $publicKeyVerifiedTimestamp') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + fromContactId, + promotionId, + publicId, + threshold, + $driftBlobEquality.hash(announcementShare), + publicKeyVerifiedTimestamp, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is UserDiscoveryOtherPromotionsData && + other.fromContactId == this.fromContactId && + other.promotionId == this.promotionId && + other.publicId == this.publicId && + other.threshold == this.threshold && + $driftBlobEquality.equals( + other.announcementShare, + this.announcementShare, + ) && + other.publicKeyVerifiedTimestamp == this.publicKeyVerifiedTimestamp); +} + +class UserDiscoveryOtherPromotionsCompanion + extends UpdateCompanion { + final Value fromContactId; + final Value promotionId; + final Value publicId; + final Value threshold; + final Value announcementShare; + final Value publicKeyVerifiedTimestamp; + final Value rowid; + const UserDiscoveryOtherPromotionsCompanion({ + this.fromContactId = const Value.absent(), + this.promotionId = const Value.absent(), + this.publicId = const Value.absent(), + this.threshold = const Value.absent(), + this.announcementShare = const Value.absent(), + this.publicKeyVerifiedTimestamp = const Value.absent(), + this.rowid = const Value.absent(), + }); + UserDiscoveryOtherPromotionsCompanion.insert({ + required int fromContactId, + required int promotionId, + required int publicId, + required int threshold, + required i2.Uint8List announcementShare, + this.publicKeyVerifiedTimestamp = const Value.absent(), + this.rowid = const Value.absent(), + }) : fromContactId = Value(fromContactId), + promotionId = Value(promotionId), + publicId = Value(publicId), + threshold = Value(threshold), + announcementShare = Value(announcementShare); + static Insertable custom({ + Expression? fromContactId, + Expression? promotionId, + Expression? publicId, + Expression? threshold, + Expression? announcementShare, + Expression? publicKeyVerifiedTimestamp, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (fromContactId != null) 'from_contact_id': fromContactId, + if (promotionId != null) 'promotion_id': promotionId, + if (publicId != null) 'public_id': publicId, + if (threshold != null) 'threshold': threshold, + if (announcementShare != null) 'announcement_share': announcementShare, + if (publicKeyVerifiedTimestamp != null) + 'public_key_verified_timestamp': publicKeyVerifiedTimestamp, + if (rowid != null) 'rowid': rowid, + }); + } + + UserDiscoveryOtherPromotionsCompanion copyWith({ + Value? fromContactId, + Value? promotionId, + Value? publicId, + Value? threshold, + Value? announcementShare, + Value? publicKeyVerifiedTimestamp, + Value? rowid, + }) { + return UserDiscoveryOtherPromotionsCompanion( + fromContactId: fromContactId ?? this.fromContactId, + promotionId: promotionId ?? this.promotionId, + publicId: publicId ?? this.publicId, + threshold: threshold ?? this.threshold, + announcementShare: announcementShare ?? this.announcementShare, + publicKeyVerifiedTimestamp: + publicKeyVerifiedTimestamp ?? this.publicKeyVerifiedTimestamp, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (fromContactId.present) { + map['from_contact_id'] = Variable(fromContactId.value); + } + if (promotionId.present) { + map['promotion_id'] = Variable(promotionId.value); + } + if (publicId.present) { + map['public_id'] = Variable(publicId.value); + } + if (threshold.present) { + map['threshold'] = Variable(threshold.value); + } + if (announcementShare.present) { + map['announcement_share'] = Variable( + announcementShare.value, + ); + } + if (publicKeyVerifiedTimestamp.present) { + map['public_key_verified_timestamp'] = Variable( + publicKeyVerifiedTimestamp.value, + ); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('UserDiscoveryOtherPromotionsCompanion(') + ..write('fromContactId: $fromContactId, ') + ..write('promotionId: $promotionId, ') + ..write('publicId: $publicId, ') + ..write('threshold: $threshold, ') + ..write('announcementShare: $announcementShare, ') + ..write('publicKeyVerifiedTimestamp: $publicKeyVerifiedTimestamp, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class UserDiscoveryOwnPromotions extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + UserDiscoveryOwnPromotions(this.attachedDatabase, [this._alias]); + late final GeneratedColumn versionId = GeneratedColumn( + 'version_id', + aliasedName, + false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL PRIMARY KEY AUTOINCREMENT', + ); + late final GeneratedColumn contactId = GeneratedColumn( + 'contact_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES contacts(user_id)ON DELETE CASCADE', + ); + late final GeneratedColumn promotion = + GeneratedColumn( + 'promotion', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + @override + List get $columns => [versionId, contactId, promotion]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'user_discovery_own_promotions'; + @override + Set get $primaryKey => {versionId}; + @override + UserDiscoveryOwnPromotionsData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return UserDiscoveryOwnPromotionsData( + versionId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}version_id'], + )!, + contactId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}contact_id'], + )!, + promotion: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}promotion'], + )!, + ); + } + + @override + UserDiscoveryOwnPromotions createAlias(String alias) { + return UserDiscoveryOwnPromotions(attachedDatabase, alias); + } + + @override + bool get dontWriteConstraints => true; +} + +class UserDiscoveryOwnPromotionsData extends DataClass + implements Insertable { + final int versionId; + final int contactId; + final i2.Uint8List promotion; + const UserDiscoveryOwnPromotionsData({ + required this.versionId, + required this.contactId, + required this.promotion, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['version_id'] = Variable(versionId); + map['contact_id'] = Variable(contactId); + map['promotion'] = Variable(promotion); + return map; + } + + UserDiscoveryOwnPromotionsCompanion toCompanion(bool nullToAbsent) { + return UserDiscoveryOwnPromotionsCompanion( + versionId: Value(versionId), + contactId: Value(contactId), + promotion: Value(promotion), + ); + } + + factory UserDiscoveryOwnPromotionsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UserDiscoveryOwnPromotionsData( + versionId: serializer.fromJson(json['versionId']), + contactId: serializer.fromJson(json['contactId']), + promotion: serializer.fromJson(json['promotion']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'versionId': serializer.toJson(versionId), + 'contactId': serializer.toJson(contactId), + 'promotion': serializer.toJson(promotion), + }; + } + + UserDiscoveryOwnPromotionsData copyWith({ + int? versionId, + int? contactId, + i2.Uint8List? promotion, + }) => UserDiscoveryOwnPromotionsData( + versionId: versionId ?? this.versionId, + contactId: contactId ?? this.contactId, + promotion: promotion ?? this.promotion, + ); + UserDiscoveryOwnPromotionsData copyWithCompanion( + UserDiscoveryOwnPromotionsCompanion data, + ) { + return UserDiscoveryOwnPromotionsData( + versionId: data.versionId.present ? data.versionId.value : this.versionId, + contactId: data.contactId.present ? data.contactId.value : this.contactId, + promotion: data.promotion.present ? data.promotion.value : this.promotion, + ); + } + + @override + String toString() { + return (StringBuffer('UserDiscoveryOwnPromotionsData(') + ..write('versionId: $versionId, ') + ..write('contactId: $contactId, ') + ..write('promotion: $promotion') + ..write(')')) + .toString(); + } + + @override + int get hashCode => + Object.hash(versionId, contactId, $driftBlobEquality.hash(promotion)); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is UserDiscoveryOwnPromotionsData && + other.versionId == this.versionId && + other.contactId == this.contactId && + $driftBlobEquality.equals(other.promotion, this.promotion)); +} + +class UserDiscoveryOwnPromotionsCompanion + extends UpdateCompanion { + final Value versionId; + final Value contactId; + final Value promotion; + const UserDiscoveryOwnPromotionsCompanion({ + this.versionId = const Value.absent(), + this.contactId = const Value.absent(), + this.promotion = const Value.absent(), + }); + UserDiscoveryOwnPromotionsCompanion.insert({ + this.versionId = const Value.absent(), + required int contactId, + required i2.Uint8List promotion, + }) : contactId = Value(contactId), + promotion = Value(promotion); + static Insertable custom({ + Expression? versionId, + Expression? contactId, + Expression? promotion, + }) { + return RawValuesInsertable({ + if (versionId != null) 'version_id': versionId, + if (contactId != null) 'contact_id': contactId, + if (promotion != null) 'promotion': promotion, + }); + } + + UserDiscoveryOwnPromotionsCompanion copyWith({ + Value? versionId, + Value? contactId, + Value? promotion, + }) { + return UserDiscoveryOwnPromotionsCompanion( + versionId: versionId ?? this.versionId, + contactId: contactId ?? this.contactId, + promotion: promotion ?? this.promotion, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (versionId.present) { + map['version_id'] = Variable(versionId.value); + } + if (contactId.present) { + map['contact_id'] = Variable(contactId.value); + } + if (promotion.present) { + map['promotion'] = Variable(promotion.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('UserDiscoveryOwnPromotionsCompanion(') + ..write('versionId: $versionId, ') + ..write('contactId: $contactId, ') + ..write('promotion: $promotion') + ..write(')')) + .toString(); + } +} + +class UserDiscoveryShares extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + UserDiscoveryShares(this.attachedDatabase, [this._alias]); + late final GeneratedColumn shareId = GeneratedColumn( + 'share_id', + aliasedName, + false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL PRIMARY KEY AUTOINCREMENT', + ); + late final GeneratedColumn share = + GeneratedColumn( + 'share', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn contactId = GeneratedColumn( + 'contact_id', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL REFERENCES contacts(user_id)ON DELETE CASCADE', + ); + @override + List get $columns => [shareId, share, contactId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'user_discovery_shares'; + @override + Set get $primaryKey => {shareId}; + @override + UserDiscoverySharesData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return UserDiscoverySharesData( + shareId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}share_id'], + )!, + share: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}share'], + )!, + contactId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}contact_id'], + ), + ); + } + + @override + UserDiscoveryShares createAlias(String alias) { + return UserDiscoveryShares(attachedDatabase, alias); + } + + @override + bool get dontWriteConstraints => true; +} + +class UserDiscoverySharesData extends DataClass + implements Insertable { + final int shareId; + final i2.Uint8List share; + final int? contactId; + const UserDiscoverySharesData({ + required this.shareId, + required this.share, + this.contactId, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['share_id'] = Variable(shareId); + map['share'] = Variable(share); + if (!nullToAbsent || contactId != null) { + map['contact_id'] = Variable(contactId); + } + return map; + } + + UserDiscoverySharesCompanion toCompanion(bool nullToAbsent) { + return UserDiscoverySharesCompanion( + shareId: Value(shareId), + share: Value(share), + contactId: contactId == null && nullToAbsent + ? const Value.absent() + : Value(contactId), + ); + } + + factory UserDiscoverySharesData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UserDiscoverySharesData( + shareId: serializer.fromJson(json['shareId']), + share: serializer.fromJson(json['share']), + contactId: serializer.fromJson(json['contactId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'shareId': serializer.toJson(shareId), + 'share': serializer.toJson(share), + 'contactId': serializer.toJson(contactId), + }; + } + + UserDiscoverySharesData copyWith({ + int? shareId, + i2.Uint8List? share, + Value contactId = const Value.absent(), + }) => UserDiscoverySharesData( + shareId: shareId ?? this.shareId, + share: share ?? this.share, + contactId: contactId.present ? contactId.value : this.contactId, + ); + UserDiscoverySharesData copyWithCompanion(UserDiscoverySharesCompanion data) { + return UserDiscoverySharesData( + shareId: data.shareId.present ? data.shareId.value : this.shareId, + share: data.share.present ? data.share.value : this.share, + contactId: data.contactId.present ? data.contactId.value : this.contactId, + ); + } + + @override + String toString() { + return (StringBuffer('UserDiscoverySharesData(') + ..write('shareId: $shareId, ') + ..write('share: $share, ') + ..write('contactId: $contactId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => + Object.hash(shareId, $driftBlobEquality.hash(share), contactId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is UserDiscoverySharesData && + other.shareId == this.shareId && + $driftBlobEquality.equals(other.share, this.share) && + other.contactId == this.contactId); +} + +class UserDiscoverySharesCompanion + extends UpdateCompanion { + final Value shareId; + final Value share; + final Value contactId; + const UserDiscoverySharesCompanion({ + this.shareId = const Value.absent(), + this.share = const Value.absent(), + this.contactId = const Value.absent(), + }); + UserDiscoverySharesCompanion.insert({ + this.shareId = const Value.absent(), + required i2.Uint8List share, + this.contactId = const Value.absent(), + }) : share = Value(share); + static Insertable custom({ + Expression? shareId, + Expression? share, + Expression? contactId, + }) { + return RawValuesInsertable({ + if (shareId != null) 'share_id': shareId, + if (share != null) 'share': share, + if (contactId != null) 'contact_id': contactId, + }); + } + + UserDiscoverySharesCompanion copyWith({ + Value? shareId, + Value? share, + Value? contactId, + }) { + return UserDiscoverySharesCompanion( + shareId: shareId ?? this.shareId, + share: share ?? this.share, + contactId: contactId ?? this.contactId, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (shareId.present) { + map['share_id'] = Variable(shareId.value); + } + if (share.present) { + map['share'] = Variable(share.value); + } + if (contactId.present) { + map['contact_id'] = Variable(contactId.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('UserDiscoverySharesCompanion(') + ..write('shareId: $shareId, ') + ..write('share: $share, ') + ..write('contactId: $contactId') + ..write(')')) + .toString(); + } +} + +class Shortcuts extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + Shortcuts(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL PRIMARY KEY AUTOINCREMENT', + ); + late final GeneratedColumn emoji = GeneratedColumn( + 'emoji', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL UNIQUE', + ); + late final GeneratedColumn usageCounter = GeneratedColumn( + 'usage_counter', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [id, emoji, usageCounter]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'shortcuts'; + @override + Set get $primaryKey => {id}; + @override + ShortcutsData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return ShortcutsData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}id'], + )!, + emoji: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}emoji'], + )!, + usageCounter: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}usage_counter'], + )!, + ); + } + + @override + Shortcuts createAlias(String alias) { + return Shortcuts(attachedDatabase, alias); + } + + @override + bool get dontWriteConstraints => true; +} + +class ShortcutsData extends DataClass implements Insertable { + final int id; + final String emoji; + final int usageCounter; + const ShortcutsData({ + required this.id, + required this.emoji, + required this.usageCounter, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['emoji'] = Variable(emoji); + map['usage_counter'] = Variable(usageCounter); + return map; + } + + ShortcutsCompanion toCompanion(bool nullToAbsent) { + return ShortcutsCompanion( + id: Value(id), + emoji: Value(emoji), + usageCounter: Value(usageCounter), + ); + } + + factory ShortcutsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return ShortcutsData( + id: serializer.fromJson(json['id']), + emoji: serializer.fromJson(json['emoji']), + usageCounter: serializer.fromJson(json['usageCounter']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'emoji': serializer.toJson(emoji), + 'usageCounter': serializer.toJson(usageCounter), + }; + } + + ShortcutsData copyWith({int? id, String? emoji, int? usageCounter}) => + ShortcutsData( + id: id ?? this.id, + emoji: emoji ?? this.emoji, + usageCounter: usageCounter ?? this.usageCounter, + ); + ShortcutsData copyWithCompanion(ShortcutsCompanion data) { + return ShortcutsData( + id: data.id.present ? data.id.value : this.id, + emoji: data.emoji.present ? data.emoji.value : this.emoji, + usageCounter: data.usageCounter.present + ? data.usageCounter.value + : this.usageCounter, + ); + } + + @override + String toString() { + return (StringBuffer('ShortcutsData(') + ..write('id: $id, ') + ..write('emoji: $emoji, ') + ..write('usageCounter: $usageCounter') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, emoji, usageCounter); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is ShortcutsData && + other.id == this.id && + other.emoji == this.emoji && + other.usageCounter == this.usageCounter); +} + +class ShortcutsCompanion extends UpdateCompanion { + final Value id; + final Value emoji; + final Value usageCounter; + const ShortcutsCompanion({ + this.id = const Value.absent(), + this.emoji = const Value.absent(), + this.usageCounter = const Value.absent(), + }); + ShortcutsCompanion.insert({ + this.id = const Value.absent(), + required String emoji, + this.usageCounter = const Value.absent(), + }) : emoji = Value(emoji); + static Insertable custom({ + Expression? id, + Expression? emoji, + Expression? usageCounter, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (emoji != null) 'emoji': emoji, + if (usageCounter != null) 'usage_counter': usageCounter, + }); + } + + ShortcutsCompanion copyWith({ + Value? id, + Value? emoji, + Value? usageCounter, + }) { + return ShortcutsCompanion( + id: id ?? this.id, + emoji: emoji ?? this.emoji, + usageCounter: usageCounter ?? this.usageCounter, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (emoji.present) { + map['emoji'] = Variable(emoji.value); + } + if (usageCounter.present) { + map['usage_counter'] = Variable(usageCounter.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('ShortcutsCompanion(') + ..write('id: $id, ') + ..write('emoji: $emoji, ') + ..write('usageCounter: $usageCounter') + ..write(')')) + .toString(); + } +} + +class ShortcutMembers extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + ShortcutMembers(this.attachedDatabase, [this._alias]); + late final GeneratedColumn shortcutId = GeneratedColumn( + 'shortcut_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL REFERENCES shortcuts(id)ON DELETE CASCADE', + ); + late final GeneratedColumn groupId = GeneratedColumn( + 'group_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES "groups"(group_id)ON DELETE CASCADE', + ); + @override + List get $columns => [shortcutId, groupId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'shortcut_members'; + @override + Set get $primaryKey => {shortcutId, groupId}; + @override + ShortcutMembersData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return ShortcutMembersData( + shortcutId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}shortcut_id'], + )!, + groupId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}group_id'], + )!, + ); + } + + @override + ShortcutMembers createAlias(String alias) { + return ShortcutMembers(attachedDatabase, alias); + } + + @override + List get customConstraints => const [ + 'PRIMARY KEY(shortcut_id, group_id)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class ShortcutMembersData extends DataClass + implements Insertable { + final int shortcutId; + final String groupId; + const ShortcutMembersData({required this.shortcutId, required this.groupId}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['shortcut_id'] = Variable(shortcutId); + map['group_id'] = Variable(groupId); + return map; + } + + ShortcutMembersCompanion toCompanion(bool nullToAbsent) { + return ShortcutMembersCompanion( + shortcutId: Value(shortcutId), + groupId: Value(groupId), + ); + } + + factory ShortcutMembersData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return ShortcutMembersData( + shortcutId: serializer.fromJson(json['shortcutId']), + groupId: serializer.fromJson(json['groupId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'shortcutId': serializer.toJson(shortcutId), + 'groupId': serializer.toJson(groupId), + }; + } + + ShortcutMembersData copyWith({int? shortcutId, String? groupId}) => + ShortcutMembersData( + shortcutId: shortcutId ?? this.shortcutId, + groupId: groupId ?? this.groupId, + ); + ShortcutMembersData copyWithCompanion(ShortcutMembersCompanion data) { + return ShortcutMembersData( + shortcutId: data.shortcutId.present + ? data.shortcutId.value + : this.shortcutId, + groupId: data.groupId.present ? data.groupId.value : this.groupId, + ); + } + + @override + String toString() { + return (StringBuffer('ShortcutMembersData(') + ..write('shortcutId: $shortcutId, ') + ..write('groupId: $groupId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(shortcutId, groupId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is ShortcutMembersData && + other.shortcutId == this.shortcutId && + other.groupId == this.groupId); +} + +class ShortcutMembersCompanion extends UpdateCompanion { + final Value shortcutId; + final Value groupId; + final Value rowid; + const ShortcutMembersCompanion({ + this.shortcutId = const Value.absent(), + this.groupId = const Value.absent(), + this.rowid = const Value.absent(), + }); + ShortcutMembersCompanion.insert({ + required int shortcutId, + required String groupId, + this.rowid = const Value.absent(), + }) : shortcutId = Value(shortcutId), + groupId = Value(groupId); + static Insertable custom({ + Expression? shortcutId, + Expression? groupId, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (shortcutId != null) 'shortcut_id': shortcutId, + if (groupId != null) 'group_id': groupId, + if (rowid != null) 'rowid': rowid, + }); + } + + ShortcutMembersCompanion copyWith({ + Value? shortcutId, + Value? groupId, + Value? rowid, + }) { + return ShortcutMembersCompanion( + shortcutId: shortcutId ?? this.shortcutId, + groupId: groupId ?? this.groupId, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (shortcutId.present) { + map['shortcut_id'] = Variable(shortcutId.value); + } + if (groupId.present) { + map['group_id'] = Variable(groupId.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('ShortcutMembersCompanion(') + ..write('shortcutId: $shortcutId, ') + ..write('groupId: $groupId, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class DatabaseAtV21 extends GeneratedDatabase { + DatabaseAtV21(QueryExecutor e) : super(e); + late final Contacts contacts = Contacts(this); + late final Groups groups = Groups(this); + late final MediaFiles mediaFiles = MediaFiles(this); + late final Messages messages = Messages(this); + late final MessageHistories messageHistories = MessageHistories(this); + late final Reactions reactions = Reactions(this); + late final GroupMembers groupMembers = GroupMembers(this); + late final Receipts receipts = Receipts(this); + late final ReceivedReceipts receivedReceipts = ReceivedReceipts(this); + late final SignalIdentityKeyStores signalIdentityKeyStores = + SignalIdentityKeyStores(this); + late final SignalPreKeyStores signalPreKeyStores = SignalPreKeyStores(this); + late final SignalSenderKeyStores signalSenderKeyStores = + SignalSenderKeyStores(this); + late final SignalSessionStores signalSessionStores = SignalSessionStores( + this, + ); + late final SignalSignedPreKeyStores signalSignedPreKeyStores = + SignalSignedPreKeyStores(this); + late final MessageActions messageActions = MessageActions(this); + late final GroupHistories groupHistories = GroupHistories(this); + late final KeyVerifications keyVerifications = KeyVerifications(this); + late final VerificationTokens verificationTokens = VerificationTokens(this); + late final UserDiscoveryAnnouncedUsers userDiscoveryAnnouncedUsers = + UserDiscoveryAnnouncedUsers(this); + late final UserDiscoveryUserRelations userDiscoveryUserRelations = + UserDiscoveryUserRelations(this); + late final UserDiscoveryOtherPromotions userDiscoveryOtherPromotions = + UserDiscoveryOtherPromotions(this); + late final UserDiscoveryOwnPromotions userDiscoveryOwnPromotions = + UserDiscoveryOwnPromotions(this); + late final UserDiscoveryShares userDiscoveryShares = UserDiscoveryShares( + this, + ); + late final Shortcuts shortcuts = Shortcuts(this); + late final ShortcutMembers shortcutMembers = ShortcutMembers(this); + @override + Iterable> get allTables => + allSchemaEntities.whereType>(); + @override + List get allSchemaEntities => [ + contacts, + groups, + mediaFiles, + messages, + messageHistories, + reactions, + groupMembers, + receipts, + receivedReceipts, + signalIdentityKeyStores, + signalPreKeyStores, + signalSenderKeyStores, + signalSessionStores, + signalSignedPreKeyStores, + messageActions, + groupHistories, + keyVerifications, + verificationTokens, + userDiscoveryAnnouncedUsers, + userDiscoveryUserRelations, + userDiscoveryOtherPromotions, + userDiscoveryOwnPromotions, + userDiscoveryShares, + shortcuts, + shortcutMembers, + ]; + @override + StreamQueryUpdateRules get streamUpdateRules => const StreamQueryUpdateRules([ + WritePropagation( + on: TableUpdateQuery.onTableName( + 'groups', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('messages', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'media_files', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('messages', kind: UpdateKind.update)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'messages', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('message_histories', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'contacts', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('message_histories', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'messages', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('reactions', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'contacts', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('reactions', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'groups', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('group_members', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'contacts', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('receipts', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'messages', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('receipts', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'messages', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('message_actions', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'contacts', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('message_actions', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'groups', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('group_histories', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'contacts', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('key_verifications', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'contacts', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('key_verifications', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'user_discovery_announced_users', + limitUpdateKind: UpdateKind.delete, + ), + result: [ + TableUpdate('user_discovery_user_relations', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'contacts', + limitUpdateKind: UpdateKind.delete, + ), + result: [ + TableUpdate('user_discovery_user_relations', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'contacts', + limitUpdateKind: UpdateKind.delete, + ), + result: [ + TableUpdate('user_discovery_other_promotions', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'contacts', + limitUpdateKind: UpdateKind.delete, + ), + result: [ + TableUpdate('user_discovery_own_promotions', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'contacts', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('user_discovery_shares', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'shortcuts', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('shortcut_members', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'groups', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('shortcut_members', kind: UpdateKind.delete)], + ), + ]); + @override + int get schemaVersion => 21; +} diff --git a/test/features/link_parser_test.dart b/test/features/link_parser_test.dart index 03e206cd..37d09e63 100644 --- a/test/features/link_parser_test.dart +++ b/test/features/link_parser_test.dart @@ -57,20 +57,6 @@ void main() { shareAction: 70, likeAction: 90, ), - LinkParserTest( - title: 'Kuketz-Blog 🛡 (@kuketzblog@social.tchncs.de)', - url: 'https://social.tchncs.de/@kuketzblog/115898752560771936', - siteName: 'Mastodon', - desc: - 'AWS verspricht jetzt »Souveränität« mit einem »europäischen« Cloud-Angebot – Standort Deutschland, großes Vertrauens-Theater.\n' - '\n' - 'Nur: Souveränität ist keine Postleitzahl. Wenn der Anbieter Amazon heißt, bleibt es dasselbe Märchen mit neuem Umschlag: Der Cloud Act, FISA etc. gilt trotzdem. US-Recht schlägt Geografie. Das Gerede von »Souveränität« ist kein Konzept, sondern Marketing.\n' - '\n' - 'https://www.heise.de/news/AWS-verspricht-Souveraenitaet-mit-europaeischem-Cloudangebot-11141800.html', - vendor: Vendor.mastodonSocialMediaPosting, - shareAction: 15, - likeAction: 190, - ), LinkParserTest( title: 'David Kriesel: Traue keinem Scan, den du nicht selbst gefälscht hast', diff --git a/test/services/passwordless_recovery_service_test.dart b/test/services/passwordless_recovery_service_test.dart new file mode 100644 index 00000000..b7f8d023 --- /dev/null +++ b/test/services/passwordless_recovery_service_test.dart @@ -0,0 +1,610 @@ +// ignore_for_file: strict_raw_type + +import 'dart:convert' show utf8; +import 'dart:io'; + +import 'package:clock/clock.dart'; +import 'package:crypto/crypto.dart'; +import 'package:drift/drift.dart' hide isNotNull, isNull; +import 'package:drift/native.dart'; +import 'package:fixnum/fixnum.dart'; +import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; +import 'package:twonly/core/bridge.dart' as bridge; +import 'package:twonly/core/frb_generated.dart'; +import 'package:twonly/globals.dart'; +import 'package:twonly/locator.dart'; +import 'package:twonly/src/callbacks/callbacks.dart'; +import 'package:twonly/src/database/twonly.db.dart'; +import 'package:twonly/src/model/json/userdata.model.dart'; +import 'package:twonly/src/model/protobuf/api/websocket/server_to_client.pb.dart' + as api_pb; +import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart' + as pb; +import 'package:twonly/src/services/api.service.dart'; +import 'package:twonly/src/services/api/utils.api.dart'; +import 'package:twonly/src/services/passwordless_recovery.service.dart'; +import 'package:twonly/src/services/signal/identity.signal.dart'; +import 'package:twonly/src/services/signal/session.signal.dart'; +import 'package:twonly/src/services/user.service.dart'; +import 'package:twonly/src/utils/log.dart'; + +import '../mocks/platform_channels.dart'; + +class MockApiService extends ApiService { + final List<(List, List?)> registeredPasswordLessRecoveries = []; + final List<(int, Uint8List, List?)> sentTextMessages = []; + + @override + Future registerPasswordLessRecovery( + List encryptedServerKey, + List? pinUnlockToken, + ) async { + registeredPasswordLessRecoveries.add((encryptedServerKey, pinUnlockToken)); + return Result.success(api_pb.Response_Ok()); + } + + @override + Future sendTextMessage( + int target, + Uint8List msg, + List? pushData, + ) async { + sentTextMessages.add((target, msg, pushData)); + return Result.success(api_pb.Response_Ok()); + } + + @override + Future updateSignedPreKey( + int id, + List key, + List signature, + ) async { + return Result.success(api_pb.Response_Ok()); + } +} + +void main() { + if (!Platform.isMacOS) { + return; + } + + TestWidgetsFlutterBinding.ensureInitialized(); + + late Directory tempDir; + + setUpAll(() async { + Log.init(); + driftRuntimeOptions.dontWarnAboutMultipleDatabases = true; + final dylibPath = + '${Directory.current.path}/rust/target/debug/librust_lib_twonly.dylib'; + if (File(dylibPath).existsSync()) { + await RustLib.init( + externalLibrary: ExternalLibrary.open(dylibPath), + ); + } else { + await RustLib.init(); + } + await initFlutterCallbacksForRust(); + + tempDir = Directory.systemTemp.createTempSync('twonly_passwordless_test_'); + AppEnvironment.initTesting( + customCacheDir: tempDir.path, + customSupportDir: tempDir.path, + ); + + await bridge.initializeTwonlyFlutter( + config: bridge.InitConfig( + databaseDir: tempDir.path, + dataDir: tempDir.path, + ), + ); + }); + + setUp(() async { + setupPlatformChannelMocks(); + await locator.reset(); + final dbFile = File('${tempDir.path}/twonly.sqlite'); + if (dbFile.existsSync()) { + dbFile.deleteSync(); + } + + locator + ..registerSingleton( + TwonlyDB(NativeDatabase(dbFile)), + ) + ..registerSingleton(UserService()) + ..registerSingleton(MockApiService()); + + userService.currentUser = UserData( + userId: 1, + username: 'me', + displayName: 'Me', + subscriptionPlan: 'Free', + currentSetupPage: null, + appVersion: 100, + ); + userService.isUserCreated = true; + await UserService.save(userService.currentUser); + + await createIfNotExistsSignalIdentity(); + }); + + tearDown(() async { + try { + await twonlyDB.close(); + } catch (_) {} + }); + + tearDownAll(() async { + if (tempDir.existsSync()) { + try { + tempDir.deleteSync(recursive: true); + } catch (_) {} + } + }); + + Future setupSignalSession(int contactId) async { + final identityKeyPair = generateIdentityKeyPair(); + final registrationId = generateRegistrationId(true); + final signedPreKey = generateSignedPreKey(identityKeyPair, 1); + final preKey = generatePreKeys(1, 1).first; + + final responseUserData = api_pb.Response_UserData() + ..userId = Int64(contactId) + ..username = utf8.encode('user_$contactId') + ..registrationId = Int64(registrationId) + ..publicIdentityKey = identityKeyPair.getPublicKey().serialize() + ..signedPrekey = signedPreKey.getKeyPair().publicKey.serialize() + ..signedPrekeyId = Int64(signedPreKey.id) + ..signedPrekeySignature = signedPreKey.signature; + + responseUserData.prekeys.add( + api_pb.Response_PreKey() + ..id = Int64(preKey.id) + ..prekey = preKey.getKeyPair().publicKey.serialize(), + ); + + final success = await processSignalUserData(responseUserData); + expect(success, isTrue); + } + + group('PasswordlessRecoveryService - enablePasswordlessRecovery', () { + test('works with SecondFactorType.none', () async { + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert(userId: const Value(2), username: 'friend_2'), + ); + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert(userId: const Value(3), username: 'friend_3'), + ); + + final success = + await PasswordlessRecoveryService.enablePasswordlessRecovery( + trustedFriendIds: [2, 3], + secondFactorType: SecondFactorType.none, + secondFactorValue: '', + threshold: 2, + ); + + expect(success, isTrue); + + final c2 = await twonlyDB.contactsDao.getContactById(2); + final c3 = await twonlyDB.contactsDao.getContactById(3); + + expect(c2?.recoveryIsTrustedFriend, isTrue); + expect(c3?.recoveryIsTrustedFriend, isTrue); + expect(c2?.recoverySecretShare, isNotNull); + expect(c3?.recoverySecretShare, isNotNull); + expect(c2?.recoveryLastHeartbeat, isNull); + expect(c3?.recoveryLastHeartbeat, isNull); + }); + + test('works with SecondFactorType.email', () async { + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert(userId: const Value(2), username: 'friend_2'), + ); + + final success = + await PasswordlessRecoveryService.enablePasswordlessRecovery( + trustedFriendIds: [2], + secondFactorType: SecondFactorType.email, + secondFactorValue: 'a_very_long_email_addr@gmail.com', + threshold: 1, + ); + + expect(success, isTrue); + + final c2 = await twonlyDB.contactsDao.getContactById(2); + expect(c2?.recoveryIsTrustedFriend, isTrue); + expect(c2?.recoverySecretShare, isNotNull); + }); + + test('works with SecondFactorType.pin', () async { + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert(userId: const Value(2), username: 'friend_2'), + ); + + final success = + await PasswordlessRecoveryService.enablePasswordlessRecovery( + trustedFriendIds: [2], + secondFactorType: SecondFactorType.pin, + secondFactorValue: '123456', + threshold: 1, + ); + + expect(success, isTrue); + + final c2 = await twonlyDB.contactsDao.getContactById(2); + expect(c2?.recoveryIsTrustedFriend, isTrue); + expect(c2?.recoverySecretShare, isNotNull); + }); + + test('sends delete messages to old trusted friends', () async { + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert( + userId: const Value(2), + username: 'friend_2', + recoveryIsTrustedFriend: const Value(true), + ), + ); + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert(userId: const Value(3), username: 'friend_3'), + ); + + await setupSignalSession(2); + await setupSignalSession(3); + + final mockApi = apiService as MockApiService; + mockApi.sentTextMessages.clear(); + + final success = + await PasswordlessRecoveryService.enablePasswordlessRecovery( + trustedFriendIds: [3], + secondFactorType: SecondFactorType.none, + secondFactorValue: '', + threshold: 1, + ); + + expect(success, isTrue); + + // Verify old friend got a delete message + expect(mockApi.sentTextMessages.isNotEmpty, isTrue); + final deleteMsg = mockApi.sentTextMessages.firstWhere((t) => t.$1 == 2); + expect(deleteMsg, isNotNull); + + final oldFriend = await twonlyDB.contactsDao.getContactById(2); + expect(oldFriend?.recoveryIsTrustedFriend, isFalse); + }); + }); + + group('PasswordlessRecoveryService - performHeartbeat', () { + test( + 'triggers server registration based on lastServerHeartbeat time', + () async { + final config = PasswordLessRecovery() + ..encryptedServerKey = Uint8List.fromList([1, 2, 3]) + ..pinUnlockToken = Uint8List.fromList([4, 5, 6]); + + await UserService.update((u) => u.passwordLessRecovery = config); + + final mockApi = apiService as MockApiService; + mockApi.registeredPasswordLessRecoveries.clear(); + + // Case 1: lastServerHeartbeat is null -> should trigger registration + await PasswordlessRecoveryService.performHeartbeat(); + expect(mockApi.registeredPasswordLessRecoveries.length, 1); + expect( + userService.currentUser.passwordLessRecovery?.lastServerHeartbeat, + isNotNull, + ); + + // Case 2: lastServerHeartbeat is < 30 days old -> should not trigger + mockApi.registeredPasswordLessRecoveries.clear(); + final now = clock.now(); + await UserService.update( + (u) => u.passwordLessRecovery?.lastServerHeartbeat = now.subtract( + const Duration(days: 15), + ), + ); + await PasswordlessRecoveryService.performHeartbeat(); + expect(mockApi.registeredPasswordLessRecoveries.length, 0); + + // Case 3: lastServerHeartbeat is > 30 days old -> should trigger + await withClock(Clock.fixed(now), () async { + await UserService.update( + (u) => u.passwordLessRecovery?.lastServerHeartbeat = now.subtract( + const Duration(days: 31), + ), + ); + await PasswordlessRecoveryService.performHeartbeat(); + expect(mockApi.registeredPasswordLessRecoveries.length, 1); + expect( + userService.currentUser.passwordLessRecovery?.lastServerHeartbeat, + now, + ); + }); + }, + ); + + test( + 'sends secret shares to trusted friends with null recoveryLastHeartbeat', + () async { + final config = PasswordLessRecovery() + ..encryptedServerKey = Uint8List.fromList([1, 2, 3]) + ..pinUnlockToken = Uint8List.fromList([4, 5, 6]); + await UserService.update((u) => u.passwordLessRecovery = config); + + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert( + userId: const Value(2), + username: 'friend_2', + recoveryIsTrustedFriend: const Value(true), + recoverySecretShare: Value(Uint8List.fromList([1, 2, 3])), + recoveryLastHeartbeat: const Value(null), + ), + ); + + await setupSignalSession(2); + + final mockApi = apiService as MockApiService; + mockApi.sentTextMessages.clear(); + + final baseTime = DateTime(2026, 6, 20, 12, 0); + + await withClock(Clock.fixed(baseTime), () async { + await PasswordlessRecoveryService.performHeartbeat(); + }); + + // Verify message sent + expect(mockApi.sentTextMessages.length, 1); + expect(mockApi.sentTextMessages.first.$1, 2); + + // Verify db update + final c2 = await twonlyDB.contactsDao.getContactById(2); + expect(c2?.recoveryLastHeartbeat, baseTime); + + // Verify calling again does not resend + mockApi.sentTextMessages.clear(); + await PasswordlessRecoveryService.performHeartbeat(); + expect(mockApi.sentTextMessages.length, 0); + }, + ); + + test( + 'sends heartbeat to friends who chose us as a trusted friend based on time', + () async { + final config = PasswordLessRecovery() + ..encryptedServerKey = Uint8List.fromList([1, 2, 3]) + ..pinUnlockToken = Uint8List.fromList([4, 5, 6]); + await UserService.update((u) => u.passwordLessRecovery = config); + + final shareBytes = Uint8List.fromList([10, 20, 30]); + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert( + userId: const Value(3), + username: 'friend_3', + recoveryContactsSecretShare: Value(shareBytes), + recoveryContactsLastHeartbeat: const Value(null), + ), + ); + + await setupSignalSession(3); + + final mockApi = apiService as MockApiService; + mockApi.sentTextMessages.clear(); + + final baseTime = DateTime(2026, 6, 20, 12, 0); + + // Case 1: recoveryContactsLastHeartbeat is null -> should send + await withClock(Clock.fixed(baseTime), () async { + await PasswordlessRecoveryService.performHeartbeat(); + }); + expect(mockApi.sentTextMessages.length, 1); + expect(mockApi.sentTextMessages.first.$1, 3); + + final c3 = await twonlyDB.contactsDao.getContactById(3); + expect(c3?.recoveryContactsLastHeartbeat, baseTime); + + // Case 2: last heartbeat is < 7 days -> should not send + mockApi.sentTextMessages.clear(); + await withClock( + Clock.fixed(baseTime.add(const Duration(days: 5))), + () async { + await PasswordlessRecoveryService.performHeartbeat(); + }, + ); + expect(mockApi.sentTextMessages.length, 0); + + // Case 3: last heartbeat is > 7 days -> should send + mockApi.sentTextMessages.clear(); + final targetTime = baseTime.add(const Duration(days: 8)); + await withClock(Clock.fixed(targetTime), () async { + await PasswordlessRecoveryService.performHeartbeat(); + }); + expect(mockApi.sentTextMessages.length, 1); + + final c3Updated = await twonlyDB.contactsDao.getContactById(3); + expect(c3Updated?.recoveryContactsLastHeartbeat, targetTime); + }, + ); + + test( + 'sends heartbeat to friends who chose us as a trusted friend even if our config is null', + () async { + await UserService.update((u) => u.passwordLessRecovery = null); + + final shareBytes = Uint8List.fromList([10, 20, 30]); + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert( + userId: const Value(4), + username: 'friend_4', + recoveryContactsSecretShare: Value(shareBytes), + recoveryContactsLastHeartbeat: const Value(null), + ), + ); + + await setupSignalSession(4); + + final mockApi = apiService as MockApiService; + mockApi.sentTextMessages.clear(); + + final baseTime = DateTime(2026, 6, 20, 12, 0); + + await withClock(Clock.fixed(baseTime), () async { + await PasswordlessRecoveryService.performHeartbeat(); + }); + + expect(mockApi.sentTextMessages.length, 1); + expect(mockApi.sentTextMessages.first.$1, 4); + }, + ); + }); + + group('PasswordlessRecoveryService - handlePasswordlessRecovery', () { + test( + 'handlePasswordlessRecovery deletes share when delete is true', + () async { + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert( + userId: const Value(4), + username: 'friend_4', + recoveryContactsSecretShare: Value(Uint8List.fromList([7, 8, 9])), + recoveryContactsLastHeartbeat: Value(DateTime.now()), + ), + ); + + final msg = pb.EncryptedContent_PasswordLessRecovery()..delete = true; + + await PasswordlessRecoveryService.handlePasswordlessRecovery( + 4, + msg, + 'receipt_id_1', + ); + + final c4 = await twonlyDB.contactsDao.getContactById(4); + expect(c4?.recoveryContactsSecretShare, isNull); + expect(c4?.recoveryContactsLastHeartbeat, isNull); + }, + ); + + test( + 'handlePasswordlessRecovery saves share when delete is false', + () async { + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert( + userId: const Value(4), + username: 'friend_4', + ), + ); + + final msg = pb.EncryptedContent_PasswordLessRecovery() + ..delete = false + ..recoverySecretShare = [11, 22, 33]; + + await PasswordlessRecoveryService.handlePasswordlessRecovery( + 4, + msg, + 'receipt_id_2', + ); + + final c4 = await twonlyDB.contactsDao.getContactById(4); + expect( + c4?.recoveryContactsSecretShare, + Uint8List.fromList([11, 22, 33]), + ); + expect(c4?.recoveryContactsLastHeartbeat, isNull); + }, + ); + }); + + group('PasswordlessRecoveryService - handlePasswordlessRecoveryHeartbeat', () { + test('sends delete message back if stored share is null', () async { + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert(userId: const Value(5), username: 'friend_5'), + ); + + await setupSignalSession(5); + + final mockApi = apiService as MockApiService; + mockApi.sentTextMessages.clear(); + + final msg = pb.EncryptedContent_PasswordLessRecoveryHeartbeat() + ..hash = [1, 2, 3]; + + await PasswordlessRecoveryService.handlePasswordlessRecoveryHeartbeat( + 5, + msg, + 'receipt_id_3', + ); + + // Await unawaited sendCipherText call + await Future.delayed(const Duration(milliseconds: 100)); + + // We expect a delete message sent back + expect(mockApi.sentTextMessages.isNotEmpty, isTrue); + expect(mockApi.sentTextMessages.first.$1, 5); + }); + + test( + 'updates recoveryLastHeartbeat to clock.now() when hash matches', + () async { + final shareBytes = Uint8List.fromList([1, 2, 3]); + final hashBytes = sha256.convert(shareBytes).bytes; + + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert( + userId: const Value(5), + username: 'friend_5', + recoverySecretShare: Value(shareBytes), + ), + ); + + final msg = pb.EncryptedContent_PasswordLessRecoveryHeartbeat() + ..hash = hashBytes; + + final now = DateTime(2026, 6, 20, 12, 0); + + await withClock(Clock.fixed(now), () async { + await PasswordlessRecoveryService.handlePasswordlessRecoveryHeartbeat( + 5, + msg, + 'receipt_id_4', + ); + }); + + final c5 = await twonlyDB.contactsDao.getContactById(5); + expect(c5?.recoveryLastHeartbeat, now); + }, + ); + + test( + 'sets recoveryLastHeartbeat to null when hash does not match', + () async { + final shareBytes = Uint8List.fromList([1, 2, 3]); + final wrongHashBytes = sha256.convert([4, 5, 6]).bytes; + + await twonlyDB.contactsDao.insertContact( + ContactsCompanion.insert( + userId: const Value(5), + username: 'friend_5', + recoverySecretShare: Value(shareBytes), + recoveryLastHeartbeat: Value(DateTime.now()), + ), + ); + + final msg = pb.EncryptedContent_PasswordLessRecoveryHeartbeat() + ..hash = wrongHashBytes; + + await PasswordlessRecoveryService.handlePasswordlessRecoveryHeartbeat( + 5, + msg, + 'receipt_id_5', + ); + + final c5 = await twonlyDB.contactsDao.getContactById(5); + expect(c5?.recoveryLastHeartbeat, isNull); + }, + ); + }); +}