mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-06-25 05:04:07 +00:00
bump version and work forward
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
This commit is contained in:
parent
c28808537b
commit
690f4cae2f
24 changed files with 16231 additions and 539 deletions
|
|
@ -18,33 +18,6 @@
|
||||||
"version" : "11.2.0"
|
"version" : "11.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"identity" : "dkcamera",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/zhangao0086/DKCamera",
|
|
||||||
"state" : {
|
|
||||||
"branch" : "master",
|
|
||||||
"revision" : "5c691d11014b910aff69f960475d70e65d9dcc96"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "dkimagepickercontroller",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/zhangao0086/DKImagePickerController",
|
|
||||||
"state" : {
|
|
||||||
"branch" : "4.3.9",
|
|
||||||
"revision" : "0bdfeacefa308545adde07bef86e349186335915"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "dkphotogallery",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/zhangao0086/DKPhotoGallery",
|
|
||||||
"state" : {
|
|
||||||
"branch" : "master",
|
|
||||||
"revision" : "311c1bc7a94f1538f82773a79c84374b12a2ef3d"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"identity" : "firebase-ios-sdk",
|
"identity" : "firebase-ios-sdk",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
|
|
@ -153,15 +126,6 @@
|
||||||
"version" : "2.4.0"
|
"version" : "2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"identity" : "sdwebimage",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/SDWebImage/SDWebImage",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "2de3a496eaf6df9a1312862adcfd54acd73c39c0",
|
|
||||||
"version" : "5.21.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"identity" : "sentry-cocoa",
|
"identity" : "sentry-cocoa",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
|
|
@ -170,24 +134,6 @@
|
||||||
"revision" : "16cd512711375fa73f25ae5e373f596bdf4251ae",
|
"revision" : "16cd512711375fa73f25ae5e373f596bdf4251ae",
|
||||||
"version" : "8.58.0"
|
"version" : "8.58.0"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "swiftygif",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/kirualex/SwiftyGif.git",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "4430cbc148baa3907651d40562d96325426f409a",
|
|
||||||
"version" : "5.4.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "tocropviewcontroller",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/TimOliver/TOCropViewController",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "d4a6d8100f4b886fdbc8ae399bf144ff3e9afb7e",
|
|
||||||
"version" : "2.8.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version" : 2
|
"version" : 2
|
||||||
|
|
|
||||||
|
|
@ -18,33 +18,6 @@
|
||||||
"version" : "11.2.0"
|
"version" : "11.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"identity" : "dkcamera",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/zhangao0086/DKCamera",
|
|
||||||
"state" : {
|
|
||||||
"branch" : "master",
|
|
||||||
"revision" : "5c691d11014b910aff69f960475d70e65d9dcc96"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "dkimagepickercontroller",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/zhangao0086/DKImagePickerController",
|
|
||||||
"state" : {
|
|
||||||
"branch" : "4.3.9",
|
|
||||||
"revision" : "0bdfeacefa308545adde07bef86e349186335915"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "dkphotogallery",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/zhangao0086/DKPhotoGallery",
|
|
||||||
"state" : {
|
|
||||||
"branch" : "master",
|
|
||||||
"revision" : "311c1bc7a94f1538f82773a79c84374b12a2ef3d"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"identity" : "firebase-ios-sdk",
|
"identity" : "firebase-ios-sdk",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
|
|
@ -153,15 +126,6 @@
|
||||||
"version" : "2.4.0"
|
"version" : "2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"identity" : "sdwebimage",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/SDWebImage/SDWebImage",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "2de3a496eaf6df9a1312862adcfd54acd73c39c0",
|
|
||||||
"version" : "5.21.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"identity" : "sentry-cocoa",
|
"identity" : "sentry-cocoa",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
|
|
@ -170,24 +134,6 @@
|
||||||
"revision" : "16cd512711375fa73f25ae5e373f596bdf4251ae",
|
"revision" : "16cd512711375fa73f25ae5e373f596bdf4251ae",
|
||||||
"version" : "8.58.0"
|
"version" : "8.58.0"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "swiftygif",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/kirualex/SwiftyGif.git",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "4430cbc148baa3907651d40562d96325426f409a",
|
|
||||||
"version" : "5.4.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "tocropviewcontroller",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/TimOliver/TOCropViewController",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "d4a6d8100f4b886fdbc8ae399bf144ff3e9afb7e",
|
|
||||||
"version" : "2.8.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version" : 2
|
"version" : 2
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,18 @@ class ContactsDao extends DatabaseAccessor<TwonlyDB> with _$ContactsDaoMixin {
|
||||||
return (delete(contacts)..where((t) => t.userId.equals(userId))).go();
|
return (delete(contacts)..where((t) => t.userId.equals(userId))).go();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> resetRecoveryDataForAllContacts() async {
|
||||||
|
await update(
|
||||||
|
contacts,
|
||||||
|
).write(
|
||||||
|
const ContactsCompanion(
|
||||||
|
recoveryIsTrustedFriend: Value(false),
|
||||||
|
recoveryLastHeartbeat: Value(null),
|
||||||
|
recoverySecretShare: Value(null),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> updateContact(
|
Future<void> updateContact(
|
||||||
int userId,
|
int userId,
|
||||||
ContactsCompanion updatedValues,
|
ContactsCompanion updatedValues,
|
||||||
|
|
|
||||||
3107
lib/src/database/schemas/twonly_db/drift_schema_v20.json
Normal file
3107
lib/src/database/schemas/twonly_db/drift_schema_v20.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -23,17 +23,21 @@ class Contacts extends Table {
|
||||||
|
|
||||||
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
||||||
|
|
||||||
// contact_versions: HashMap<UserID, Vec<u8>>,
|
// User Discovery
|
||||||
BlobColumn get userDiscoveryVersion => blob().nullable()();
|
BlobColumn get userDiscoveryVersion => blob().nullable()();
|
||||||
|
|
||||||
BoolColumn get userDiscoveryExcluded =>
|
BoolColumn get userDiscoveryExcluded =>
|
||||||
boolean().withDefault(const Constant(false))();
|
boolean().withDefault(const Constant(false))();
|
||||||
|
|
||||||
BoolColumn get askForFriendPromotions => boolean().nullable()();
|
|
||||||
|
|
||||||
BoolColumn get userDiscoveryManualApproved =>
|
BoolColumn get userDiscoveryManualApproved =>
|
||||||
boolean().nullable().withDefault(const Constant(false))();
|
boolean().nullable().withDefault(const Constant(false))();
|
||||||
|
|
||||||
|
// Passwordless-Recovery
|
||||||
|
BoolColumn get recoveryIsTrustedFriend =>
|
||||||
|
boolean().withDefault(const Constant(false))();
|
||||||
|
DateTimeColumn get recoveryLastHeartbeat => dateTime().nullable()();
|
||||||
|
BlobColumn get recoverySecretShare => blob().nullable()();
|
||||||
|
|
||||||
|
BoolColumn get askForFriendPromotions => boolean().nullable()();
|
||||||
|
|
||||||
IntColumn get mediaSendCounter => integer().withDefault(const Constant(0))();
|
IntColumn get mediaSendCounter => integer().withDefault(const Constant(0))();
|
||||||
IntColumn get mediaReceivedCounter =>
|
IntColumn get mediaReceivedCounter =>
|
||||||
integer().withDefault(const Constant(0))();
|
integer().withDefault(const Constant(0))();
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ class TwonlyDB extends _$TwonlyDB {
|
||||||
TwonlyDB.forTesting(DatabaseConnection super.connection);
|
TwonlyDB.forTesting(DatabaseConnection super.connection);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 19;
|
int get schemaVersion => 20;
|
||||||
|
|
||||||
static QueryExecutor _openConnection() {
|
static QueryExecutor _openConnection() {
|
||||||
final connection = driftDatabase(
|
final connection = driftDatabase(
|
||||||
|
|
@ -245,6 +245,20 @@ class TwonlyDB extends _$TwonlyDB {
|
||||||
schema.keyVerifications.verifiedBy,
|
schema.keyVerifications.verifiedBy,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
from19To20: (m, schema) async {
|
||||||
|
await m.addColumn(
|
||||||
|
schema.contacts,
|
||||||
|
schema.contacts.recoveryIsTrustedFriend,
|
||||||
|
);
|
||||||
|
await m.addColumn(
|
||||||
|
schema.contacts,
|
||||||
|
schema.contacts.recoveryLastHeartbeat,
|
||||||
|
);
|
||||||
|
await m.addColumn(
|
||||||
|
schema.contacts,
|
||||||
|
schema.contacts.recoverySecretShare,
|
||||||
|
);
|
||||||
|
},
|
||||||
)(m, from, to);
|
)(m, from, to);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -200,20 +200,6 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
),
|
),
|
||||||
defaultValue: const Constant(false),
|
defaultValue: const Constant(false),
|
||||||
);
|
);
|
||||||
static const VerificationMeta _askForFriendPromotionsMeta =
|
|
||||||
const VerificationMeta('askForFriendPromotions');
|
|
||||||
@override
|
|
||||||
late final GeneratedColumn<bool> askForFriendPromotions =
|
|
||||||
GeneratedColumn<bool>(
|
|
||||||
'ask_for_friend_promotions',
|
|
||||||
aliasedName,
|
|
||||||
true,
|
|
||||||
type: DriftSqlType.bool,
|
|
||||||
requiredDuringInsert: false,
|
|
||||||
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
|
||||||
'CHECK ("ask_for_friend_promotions" IN (0, 1))',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
static const VerificationMeta _userDiscoveryManualApprovedMeta =
|
static const VerificationMeta _userDiscoveryManualApprovedMeta =
|
||||||
const VerificationMeta('userDiscoveryManualApproved');
|
const VerificationMeta('userDiscoveryManualApproved');
|
||||||
@override
|
@override
|
||||||
|
|
@ -229,6 +215,57 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
),
|
),
|
||||||
defaultValue: const Constant(false),
|
defaultValue: const Constant(false),
|
||||||
);
|
);
|
||||||
|
static const VerificationMeta _recoveryIsTrustedFriendMeta =
|
||||||
|
const VerificationMeta('recoveryIsTrustedFriend');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<bool> recoveryIsTrustedFriend =
|
||||||
|
GeneratedColumn<bool>(
|
||||||
|
'recovery_is_trusted_friend',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.bool,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("recovery_is_trusted_friend" IN (0, 1))',
|
||||||
|
),
|
||||||
|
defaultValue: const Constant(false),
|
||||||
|
);
|
||||||
|
static const VerificationMeta _recoveryLastHeartbeatMeta =
|
||||||
|
const VerificationMeta('recoveryLastHeartbeat');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<DateTime> recoveryLastHeartbeat =
|
||||||
|
GeneratedColumn<DateTime>(
|
||||||
|
'recovery_last_heartbeat',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.dateTime,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _recoverySecretShareMeta =
|
||||||
|
const VerificationMeta('recoverySecretShare');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<Uint8List> recoverySecretShare =
|
||||||
|
GeneratedColumn<Uint8List>(
|
||||||
|
'recovery_secret_share',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.blob,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _askForFriendPromotionsMeta =
|
||||||
|
const VerificationMeta('askForFriendPromotions');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<bool> askForFriendPromotions =
|
||||||
|
GeneratedColumn<bool>(
|
||||||
|
'ask_for_friend_promotions',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.bool,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("ask_for_friend_promotions" IN (0, 1))',
|
||||||
|
),
|
||||||
|
);
|
||||||
static const VerificationMeta _mediaSendCounterMeta = const VerificationMeta(
|
static const VerificationMeta _mediaSendCounterMeta = const VerificationMeta(
|
||||||
'mediaSendCounter',
|
'mediaSendCounter',
|
||||||
);
|
);
|
||||||
|
|
@ -269,8 +306,11 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
createdAt,
|
createdAt,
|
||||||
userDiscoveryVersion,
|
userDiscoveryVersion,
|
||||||
userDiscoveryExcluded,
|
userDiscoveryExcluded,
|
||||||
askForFriendPromotions,
|
|
||||||
userDiscoveryManualApproved,
|
userDiscoveryManualApproved,
|
||||||
|
recoveryIsTrustedFriend,
|
||||||
|
recoveryLastHeartbeat,
|
||||||
|
recoverySecretShare,
|
||||||
|
askForFriendPromotions,
|
||||||
mediaSendCounter,
|
mediaSendCounter,
|
||||||
mediaReceivedCounter,
|
mediaReceivedCounter,
|
||||||
];
|
];
|
||||||
|
|
@ -399,15 +439,6 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (data.containsKey('ask_for_friend_promotions')) {
|
|
||||||
context.handle(
|
|
||||||
_askForFriendPromotionsMeta,
|
|
||||||
askForFriendPromotions.isAcceptableOrUnknown(
|
|
||||||
data['ask_for_friend_promotions']!,
|
|
||||||
_askForFriendPromotionsMeta,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (data.containsKey('user_discovery_manual_approved')) {
|
if (data.containsKey('user_discovery_manual_approved')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_userDiscoveryManualApprovedMeta,
|
_userDiscoveryManualApprovedMeta,
|
||||||
|
|
@ -417,6 +448,42 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('recovery_is_trusted_friend')) {
|
||||||
|
context.handle(
|
||||||
|
_recoveryIsTrustedFriendMeta,
|
||||||
|
recoveryIsTrustedFriend.isAcceptableOrUnknown(
|
||||||
|
data['recovery_is_trusted_friend']!,
|
||||||
|
_recoveryIsTrustedFriendMeta,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('recovery_last_heartbeat')) {
|
||||||
|
context.handle(
|
||||||
|
_recoveryLastHeartbeatMeta,
|
||||||
|
recoveryLastHeartbeat.isAcceptableOrUnknown(
|
||||||
|
data['recovery_last_heartbeat']!,
|
||||||
|
_recoveryLastHeartbeatMeta,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('recovery_secret_share')) {
|
||||||
|
context.handle(
|
||||||
|
_recoverySecretShareMeta,
|
||||||
|
recoverySecretShare.isAcceptableOrUnknown(
|
||||||
|
data['recovery_secret_share']!,
|
||||||
|
_recoverySecretShareMeta,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('ask_for_friend_promotions')) {
|
||||||
|
context.handle(
|
||||||
|
_askForFriendPromotionsMeta,
|
||||||
|
askForFriendPromotions.isAcceptableOrUnknown(
|
||||||
|
data['ask_for_friend_promotions']!,
|
||||||
|
_askForFriendPromotionsMeta,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
if (data.containsKey('media_send_counter')) {
|
if (data.containsKey('media_send_counter')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_mediaSendCounterMeta,
|
_mediaSendCounterMeta,
|
||||||
|
|
@ -504,14 +571,26 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
DriftSqlType.bool,
|
DriftSqlType.bool,
|
||||||
data['${effectivePrefix}user_discovery_excluded'],
|
data['${effectivePrefix}user_discovery_excluded'],
|
||||||
)!,
|
)!,
|
||||||
askForFriendPromotions: attachedDatabase.typeMapping.read(
|
|
||||||
DriftSqlType.bool,
|
|
||||||
data['${effectivePrefix}ask_for_friend_promotions'],
|
|
||||||
),
|
|
||||||
userDiscoveryManualApproved: attachedDatabase.typeMapping.read(
|
userDiscoveryManualApproved: attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.bool,
|
DriftSqlType.bool,
|
||||||
data['${effectivePrefix}user_discovery_manual_approved'],
|
data['${effectivePrefix}user_discovery_manual_approved'],
|
||||||
),
|
),
|
||||||
|
recoveryIsTrustedFriend: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.bool,
|
||||||
|
data['${effectivePrefix}recovery_is_trusted_friend'],
|
||||||
|
)!,
|
||||||
|
recoveryLastHeartbeat: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.dateTime,
|
||||||
|
data['${effectivePrefix}recovery_last_heartbeat'],
|
||||||
|
),
|
||||||
|
recoverySecretShare: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.blob,
|
||||||
|
data['${effectivePrefix}recovery_secret_share'],
|
||||||
|
),
|
||||||
|
askForFriendPromotions: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.bool,
|
||||||
|
data['${effectivePrefix}ask_for_friend_promotions'],
|
||||||
|
),
|
||||||
mediaSendCounter: attachedDatabase.typeMapping.read(
|
mediaSendCounter: attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.int,
|
DriftSqlType.int,
|
||||||
data['${effectivePrefix}media_send_counter'],
|
data['${effectivePrefix}media_send_counter'],
|
||||||
|
|
@ -545,8 +624,11 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
final DateTime createdAt;
|
final DateTime createdAt;
|
||||||
final Uint8List? userDiscoveryVersion;
|
final Uint8List? userDiscoveryVersion;
|
||||||
final bool userDiscoveryExcluded;
|
final bool userDiscoveryExcluded;
|
||||||
final bool? askForFriendPromotions;
|
|
||||||
final bool? userDiscoveryManualApproved;
|
final bool? userDiscoveryManualApproved;
|
||||||
|
final bool recoveryIsTrustedFriend;
|
||||||
|
final DateTime? recoveryLastHeartbeat;
|
||||||
|
final Uint8List? recoverySecretShare;
|
||||||
|
final bool? askForFriendPromotions;
|
||||||
final int mediaSendCounter;
|
final int mediaSendCounter;
|
||||||
final int mediaReceivedCounter;
|
final int mediaReceivedCounter;
|
||||||
const Contact({
|
const Contact({
|
||||||
|
|
@ -565,8 +647,11 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
this.userDiscoveryVersion,
|
this.userDiscoveryVersion,
|
||||||
required this.userDiscoveryExcluded,
|
required this.userDiscoveryExcluded,
|
||||||
this.askForFriendPromotions,
|
|
||||||
this.userDiscoveryManualApproved,
|
this.userDiscoveryManualApproved,
|
||||||
|
required this.recoveryIsTrustedFriend,
|
||||||
|
this.recoveryLastHeartbeat,
|
||||||
|
this.recoverySecretShare,
|
||||||
|
this.askForFriendPromotions,
|
||||||
required this.mediaSendCounter,
|
required this.mediaSendCounter,
|
||||||
required this.mediaReceivedCounter,
|
required this.mediaReceivedCounter,
|
||||||
});
|
});
|
||||||
|
|
@ -596,14 +681,23 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
map['user_discovery_version'] = Variable<Uint8List>(userDiscoveryVersion);
|
map['user_discovery_version'] = Variable<Uint8List>(userDiscoveryVersion);
|
||||||
}
|
}
|
||||||
map['user_discovery_excluded'] = Variable<bool>(userDiscoveryExcluded);
|
map['user_discovery_excluded'] = Variable<bool>(userDiscoveryExcluded);
|
||||||
if (!nullToAbsent || askForFriendPromotions != null) {
|
|
||||||
map['ask_for_friend_promotions'] = Variable<bool>(askForFriendPromotions);
|
|
||||||
}
|
|
||||||
if (!nullToAbsent || userDiscoveryManualApproved != null) {
|
if (!nullToAbsent || userDiscoveryManualApproved != null) {
|
||||||
map['user_discovery_manual_approved'] = Variable<bool>(
|
map['user_discovery_manual_approved'] = Variable<bool>(
|
||||||
userDiscoveryManualApproved,
|
userDiscoveryManualApproved,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
map['recovery_is_trusted_friend'] = Variable<bool>(recoveryIsTrustedFriend);
|
||||||
|
if (!nullToAbsent || recoveryLastHeartbeat != null) {
|
||||||
|
map['recovery_last_heartbeat'] = Variable<DateTime>(
|
||||||
|
recoveryLastHeartbeat,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!nullToAbsent || recoverySecretShare != null) {
|
||||||
|
map['recovery_secret_share'] = Variable<Uint8List>(recoverySecretShare);
|
||||||
|
}
|
||||||
|
if (!nullToAbsent || askForFriendPromotions != null) {
|
||||||
|
map['ask_for_friend_promotions'] = Variable<bool>(askForFriendPromotions);
|
||||||
|
}
|
||||||
map['media_send_counter'] = Variable<int>(mediaSendCounter);
|
map['media_send_counter'] = Variable<int>(mediaSendCounter);
|
||||||
map['media_received_counter'] = Variable<int>(mediaReceivedCounter);
|
map['media_received_counter'] = Variable<int>(mediaReceivedCounter);
|
||||||
return map;
|
return map;
|
||||||
|
|
@ -634,13 +728,20 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
: Value(userDiscoveryVersion),
|
: Value(userDiscoveryVersion),
|
||||||
userDiscoveryExcluded: Value(userDiscoveryExcluded),
|
userDiscoveryExcluded: Value(userDiscoveryExcluded),
|
||||||
askForFriendPromotions: askForFriendPromotions == null && nullToAbsent
|
|
||||||
? const Value.absent()
|
|
||||||
: Value(askForFriendPromotions),
|
|
||||||
userDiscoveryManualApproved:
|
userDiscoveryManualApproved:
|
||||||
userDiscoveryManualApproved == null && nullToAbsent
|
userDiscoveryManualApproved == null && nullToAbsent
|
||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
: Value(userDiscoveryManualApproved),
|
: Value(userDiscoveryManualApproved),
|
||||||
|
recoveryIsTrustedFriend: Value(recoveryIsTrustedFriend),
|
||||||
|
recoveryLastHeartbeat: recoveryLastHeartbeat == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(recoveryLastHeartbeat),
|
||||||
|
recoverySecretShare: recoverySecretShare == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(recoverySecretShare),
|
||||||
|
askForFriendPromotions: askForFriendPromotions == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(askForFriendPromotions),
|
||||||
mediaSendCounter: Value(mediaSendCounter),
|
mediaSendCounter: Value(mediaSendCounter),
|
||||||
mediaReceivedCounter: Value(mediaReceivedCounter),
|
mediaReceivedCounter: Value(mediaReceivedCounter),
|
||||||
);
|
);
|
||||||
|
|
@ -675,12 +776,21 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
userDiscoveryExcluded: serializer.fromJson<bool>(
|
userDiscoveryExcluded: serializer.fromJson<bool>(
|
||||||
json['userDiscoveryExcluded'],
|
json['userDiscoveryExcluded'],
|
||||||
),
|
),
|
||||||
askForFriendPromotions: serializer.fromJson<bool?>(
|
|
||||||
json['askForFriendPromotions'],
|
|
||||||
),
|
|
||||||
userDiscoveryManualApproved: serializer.fromJson<bool?>(
|
userDiscoveryManualApproved: serializer.fromJson<bool?>(
|
||||||
json['userDiscoveryManualApproved'],
|
json['userDiscoveryManualApproved'],
|
||||||
),
|
),
|
||||||
|
recoveryIsTrustedFriend: serializer.fromJson<bool>(
|
||||||
|
json['recoveryIsTrustedFriend'],
|
||||||
|
),
|
||||||
|
recoveryLastHeartbeat: serializer.fromJson<DateTime?>(
|
||||||
|
json['recoveryLastHeartbeat'],
|
||||||
|
),
|
||||||
|
recoverySecretShare: serializer.fromJson<Uint8List?>(
|
||||||
|
json['recoverySecretShare'],
|
||||||
|
),
|
||||||
|
askForFriendPromotions: serializer.fromJson<bool?>(
|
||||||
|
json['askForFriendPromotions'],
|
||||||
|
),
|
||||||
mediaSendCounter: serializer.fromJson<int>(json['mediaSendCounter']),
|
mediaSendCounter: serializer.fromJson<int>(json['mediaSendCounter']),
|
||||||
mediaReceivedCounter: serializer.fromJson<int>(
|
mediaReceivedCounter: serializer.fromJson<int>(
|
||||||
json['mediaReceivedCounter'],
|
json['mediaReceivedCounter'],
|
||||||
|
|
@ -708,12 +818,19 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
userDiscoveryVersion,
|
userDiscoveryVersion,
|
||||||
),
|
),
|
||||||
'userDiscoveryExcluded': serializer.toJson<bool>(userDiscoveryExcluded),
|
'userDiscoveryExcluded': serializer.toJson<bool>(userDiscoveryExcluded),
|
||||||
'askForFriendPromotions': serializer.toJson<bool?>(
|
|
||||||
askForFriendPromotions,
|
|
||||||
),
|
|
||||||
'userDiscoveryManualApproved': serializer.toJson<bool?>(
|
'userDiscoveryManualApproved': serializer.toJson<bool?>(
|
||||||
userDiscoveryManualApproved,
|
userDiscoveryManualApproved,
|
||||||
),
|
),
|
||||||
|
'recoveryIsTrustedFriend': serializer.toJson<bool>(
|
||||||
|
recoveryIsTrustedFriend,
|
||||||
|
),
|
||||||
|
'recoveryLastHeartbeat': serializer.toJson<DateTime?>(
|
||||||
|
recoveryLastHeartbeat,
|
||||||
|
),
|
||||||
|
'recoverySecretShare': serializer.toJson<Uint8List?>(recoverySecretShare),
|
||||||
|
'askForFriendPromotions': serializer.toJson<bool?>(
|
||||||
|
askForFriendPromotions,
|
||||||
|
),
|
||||||
'mediaSendCounter': serializer.toJson<int>(mediaSendCounter),
|
'mediaSendCounter': serializer.toJson<int>(mediaSendCounter),
|
||||||
'mediaReceivedCounter': serializer.toJson<int>(mediaReceivedCounter),
|
'mediaReceivedCounter': serializer.toJson<int>(mediaReceivedCounter),
|
||||||
};
|
};
|
||||||
|
|
@ -735,8 +852,11 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
DateTime? createdAt,
|
DateTime? createdAt,
|
||||||
Value<Uint8List?> userDiscoveryVersion = const Value.absent(),
|
Value<Uint8List?> userDiscoveryVersion = const Value.absent(),
|
||||||
bool? userDiscoveryExcluded,
|
bool? userDiscoveryExcluded,
|
||||||
Value<bool?> askForFriendPromotions = const Value.absent(),
|
|
||||||
Value<bool?> userDiscoveryManualApproved = const Value.absent(),
|
Value<bool?> userDiscoveryManualApproved = const Value.absent(),
|
||||||
|
bool? recoveryIsTrustedFriend,
|
||||||
|
Value<DateTime?> recoveryLastHeartbeat = const Value.absent(),
|
||||||
|
Value<Uint8List?> recoverySecretShare = const Value.absent(),
|
||||||
|
Value<bool?> askForFriendPromotions = const Value.absent(),
|
||||||
int? mediaSendCounter,
|
int? mediaSendCounter,
|
||||||
int? mediaReceivedCounter,
|
int? mediaReceivedCounter,
|
||||||
}) => Contact(
|
}) => Contact(
|
||||||
|
|
@ -759,12 +879,20 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
? userDiscoveryVersion.value
|
? userDiscoveryVersion.value
|
||||||
: this.userDiscoveryVersion,
|
: this.userDiscoveryVersion,
|
||||||
userDiscoveryExcluded: userDiscoveryExcluded ?? this.userDiscoveryExcluded,
|
userDiscoveryExcluded: userDiscoveryExcluded ?? this.userDiscoveryExcluded,
|
||||||
askForFriendPromotions: askForFriendPromotions.present
|
|
||||||
? askForFriendPromotions.value
|
|
||||||
: this.askForFriendPromotions,
|
|
||||||
userDiscoveryManualApproved: userDiscoveryManualApproved.present
|
userDiscoveryManualApproved: userDiscoveryManualApproved.present
|
||||||
? userDiscoveryManualApproved.value
|
? userDiscoveryManualApproved.value
|
||||||
: this.userDiscoveryManualApproved,
|
: this.userDiscoveryManualApproved,
|
||||||
|
recoveryIsTrustedFriend:
|
||||||
|
recoveryIsTrustedFriend ?? this.recoveryIsTrustedFriend,
|
||||||
|
recoveryLastHeartbeat: recoveryLastHeartbeat.present
|
||||||
|
? recoveryLastHeartbeat.value
|
||||||
|
: this.recoveryLastHeartbeat,
|
||||||
|
recoverySecretShare: recoverySecretShare.present
|
||||||
|
? recoverySecretShare.value
|
||||||
|
: this.recoverySecretShare,
|
||||||
|
askForFriendPromotions: askForFriendPromotions.present
|
||||||
|
? askForFriendPromotions.value
|
||||||
|
: this.askForFriendPromotions,
|
||||||
mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter,
|
mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter,
|
||||||
mediaReceivedCounter: mediaReceivedCounter ?? this.mediaReceivedCounter,
|
mediaReceivedCounter: mediaReceivedCounter ?? this.mediaReceivedCounter,
|
||||||
);
|
);
|
||||||
|
|
@ -799,12 +927,21 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
userDiscoveryExcluded: data.userDiscoveryExcluded.present
|
userDiscoveryExcluded: data.userDiscoveryExcluded.present
|
||||||
? data.userDiscoveryExcluded.value
|
? data.userDiscoveryExcluded.value
|
||||||
: this.userDiscoveryExcluded,
|
: this.userDiscoveryExcluded,
|
||||||
askForFriendPromotions: data.askForFriendPromotions.present
|
|
||||||
? data.askForFriendPromotions.value
|
|
||||||
: this.askForFriendPromotions,
|
|
||||||
userDiscoveryManualApproved: data.userDiscoveryManualApproved.present
|
userDiscoveryManualApproved: data.userDiscoveryManualApproved.present
|
||||||
? data.userDiscoveryManualApproved.value
|
? data.userDiscoveryManualApproved.value
|
||||||
: this.userDiscoveryManualApproved,
|
: 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,
|
||||||
|
askForFriendPromotions: data.askForFriendPromotions.present
|
||||||
|
? data.askForFriendPromotions.value
|
||||||
|
: this.askForFriendPromotions,
|
||||||
mediaSendCounter: data.mediaSendCounter.present
|
mediaSendCounter: data.mediaSendCounter.present
|
||||||
? data.mediaSendCounter.value
|
? data.mediaSendCounter.value
|
||||||
: this.mediaSendCounter,
|
: this.mediaSendCounter,
|
||||||
|
|
@ -832,8 +969,11 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
..write('createdAt: $createdAt, ')
|
..write('createdAt: $createdAt, ')
|
||||||
..write('userDiscoveryVersion: $userDiscoveryVersion, ')
|
..write('userDiscoveryVersion: $userDiscoveryVersion, ')
|
||||||
..write('userDiscoveryExcluded: $userDiscoveryExcluded, ')
|
..write('userDiscoveryExcluded: $userDiscoveryExcluded, ')
|
||||||
..write('askForFriendPromotions: $askForFriendPromotions, ')
|
|
||||||
..write('userDiscoveryManualApproved: $userDiscoveryManualApproved, ')
|
..write('userDiscoveryManualApproved: $userDiscoveryManualApproved, ')
|
||||||
|
..write('recoveryIsTrustedFriend: $recoveryIsTrustedFriend, ')
|
||||||
|
..write('recoveryLastHeartbeat: $recoveryLastHeartbeat, ')
|
||||||
|
..write('recoverySecretShare: $recoverySecretShare, ')
|
||||||
|
..write('askForFriendPromotions: $askForFriendPromotions, ')
|
||||||
..write('mediaSendCounter: $mediaSendCounter, ')
|
..write('mediaSendCounter: $mediaSendCounter, ')
|
||||||
..write('mediaReceivedCounter: $mediaReceivedCounter')
|
..write('mediaReceivedCounter: $mediaReceivedCounter')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
|
|
@ -841,7 +981,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hashAll([
|
||||||
userId,
|
userId,
|
||||||
username,
|
username,
|
||||||
displayName,
|
displayName,
|
||||||
|
|
@ -857,11 +997,14 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
createdAt,
|
createdAt,
|
||||||
$driftBlobEquality.hash(userDiscoveryVersion),
|
$driftBlobEquality.hash(userDiscoveryVersion),
|
||||||
userDiscoveryExcluded,
|
userDiscoveryExcluded,
|
||||||
askForFriendPromotions,
|
|
||||||
userDiscoveryManualApproved,
|
userDiscoveryManualApproved,
|
||||||
|
recoveryIsTrustedFriend,
|
||||||
|
recoveryLastHeartbeat,
|
||||||
|
$driftBlobEquality.hash(recoverySecretShare),
|
||||||
|
askForFriendPromotions,
|
||||||
mediaSendCounter,
|
mediaSendCounter,
|
||||||
mediaReceivedCounter,
|
mediaReceivedCounter,
|
||||||
);
|
]);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
|
|
@ -887,9 +1030,15 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
this.userDiscoveryVersion,
|
this.userDiscoveryVersion,
|
||||||
) &&
|
) &&
|
||||||
other.userDiscoveryExcluded == this.userDiscoveryExcluded &&
|
other.userDiscoveryExcluded == this.userDiscoveryExcluded &&
|
||||||
other.askForFriendPromotions == this.askForFriendPromotions &&
|
|
||||||
other.userDiscoveryManualApproved ==
|
other.userDiscoveryManualApproved ==
|
||||||
this.userDiscoveryManualApproved &&
|
this.userDiscoveryManualApproved &&
|
||||||
|
other.recoveryIsTrustedFriend == this.recoveryIsTrustedFriend &&
|
||||||
|
other.recoveryLastHeartbeat == this.recoveryLastHeartbeat &&
|
||||||
|
$driftBlobEquality.equals(
|
||||||
|
other.recoverySecretShare,
|
||||||
|
this.recoverySecretShare,
|
||||||
|
) &&
|
||||||
|
other.askForFriendPromotions == this.askForFriendPromotions &&
|
||||||
other.mediaSendCounter == this.mediaSendCounter &&
|
other.mediaSendCounter == this.mediaSendCounter &&
|
||||||
other.mediaReceivedCounter == this.mediaReceivedCounter);
|
other.mediaReceivedCounter == this.mediaReceivedCounter);
|
||||||
}
|
}
|
||||||
|
|
@ -910,8 +1059,11 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
final Value<DateTime> createdAt;
|
final Value<DateTime> createdAt;
|
||||||
final Value<Uint8List?> userDiscoveryVersion;
|
final Value<Uint8List?> userDiscoveryVersion;
|
||||||
final Value<bool> userDiscoveryExcluded;
|
final Value<bool> userDiscoveryExcluded;
|
||||||
final Value<bool?> askForFriendPromotions;
|
|
||||||
final Value<bool?> userDiscoveryManualApproved;
|
final Value<bool?> userDiscoveryManualApproved;
|
||||||
|
final Value<bool> recoveryIsTrustedFriend;
|
||||||
|
final Value<DateTime?> recoveryLastHeartbeat;
|
||||||
|
final Value<Uint8List?> recoverySecretShare;
|
||||||
|
final Value<bool?> askForFriendPromotions;
|
||||||
final Value<int> mediaSendCounter;
|
final Value<int> mediaSendCounter;
|
||||||
final Value<int> mediaReceivedCounter;
|
final Value<int> mediaReceivedCounter;
|
||||||
const ContactsCompanion({
|
const ContactsCompanion({
|
||||||
|
|
@ -930,8 +1082,11 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
this.createdAt = const Value.absent(),
|
this.createdAt = const Value.absent(),
|
||||||
this.userDiscoveryVersion = const Value.absent(),
|
this.userDiscoveryVersion = const Value.absent(),
|
||||||
this.userDiscoveryExcluded = const Value.absent(),
|
this.userDiscoveryExcluded = const Value.absent(),
|
||||||
this.askForFriendPromotions = const Value.absent(),
|
|
||||||
this.userDiscoveryManualApproved = const Value.absent(),
|
this.userDiscoveryManualApproved = const Value.absent(),
|
||||||
|
this.recoveryIsTrustedFriend = const Value.absent(),
|
||||||
|
this.recoveryLastHeartbeat = const Value.absent(),
|
||||||
|
this.recoverySecretShare = const Value.absent(),
|
||||||
|
this.askForFriendPromotions = const Value.absent(),
|
||||||
this.mediaSendCounter = const Value.absent(),
|
this.mediaSendCounter = const Value.absent(),
|
||||||
this.mediaReceivedCounter = const Value.absent(),
|
this.mediaReceivedCounter = const Value.absent(),
|
||||||
});
|
});
|
||||||
|
|
@ -951,8 +1106,11 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
this.createdAt = const Value.absent(),
|
this.createdAt = const Value.absent(),
|
||||||
this.userDiscoveryVersion = const Value.absent(),
|
this.userDiscoveryVersion = const Value.absent(),
|
||||||
this.userDiscoveryExcluded = const Value.absent(),
|
this.userDiscoveryExcluded = const Value.absent(),
|
||||||
this.askForFriendPromotions = const Value.absent(),
|
|
||||||
this.userDiscoveryManualApproved = const Value.absent(),
|
this.userDiscoveryManualApproved = const Value.absent(),
|
||||||
|
this.recoveryIsTrustedFriend = const Value.absent(),
|
||||||
|
this.recoveryLastHeartbeat = const Value.absent(),
|
||||||
|
this.recoverySecretShare = const Value.absent(),
|
||||||
|
this.askForFriendPromotions = const Value.absent(),
|
||||||
this.mediaSendCounter = const Value.absent(),
|
this.mediaSendCounter = const Value.absent(),
|
||||||
this.mediaReceivedCounter = const Value.absent(),
|
this.mediaReceivedCounter = const Value.absent(),
|
||||||
}) : username = Value(username);
|
}) : username = Value(username);
|
||||||
|
|
@ -972,8 +1130,11 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
Expression<DateTime>? createdAt,
|
Expression<DateTime>? createdAt,
|
||||||
Expression<Uint8List>? userDiscoveryVersion,
|
Expression<Uint8List>? userDiscoveryVersion,
|
||||||
Expression<bool>? userDiscoveryExcluded,
|
Expression<bool>? userDiscoveryExcluded,
|
||||||
Expression<bool>? askForFriendPromotions,
|
|
||||||
Expression<bool>? userDiscoveryManualApproved,
|
Expression<bool>? userDiscoveryManualApproved,
|
||||||
|
Expression<bool>? recoveryIsTrustedFriend,
|
||||||
|
Expression<DateTime>? recoveryLastHeartbeat,
|
||||||
|
Expression<Uint8List>? recoverySecretShare,
|
||||||
|
Expression<bool>? askForFriendPromotions,
|
||||||
Expression<int>? mediaSendCounter,
|
Expression<int>? mediaSendCounter,
|
||||||
Expression<int>? mediaReceivedCounter,
|
Expression<int>? mediaReceivedCounter,
|
||||||
}) {
|
}) {
|
||||||
|
|
@ -997,10 +1158,16 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
'user_discovery_version': userDiscoveryVersion,
|
'user_discovery_version': userDiscoveryVersion,
|
||||||
if (userDiscoveryExcluded != null)
|
if (userDiscoveryExcluded != null)
|
||||||
'user_discovery_excluded': userDiscoveryExcluded,
|
'user_discovery_excluded': userDiscoveryExcluded,
|
||||||
if (askForFriendPromotions != null)
|
|
||||||
'ask_for_friend_promotions': askForFriendPromotions,
|
|
||||||
if (userDiscoveryManualApproved != null)
|
if (userDiscoveryManualApproved != null)
|
||||||
'user_discovery_manual_approved': userDiscoveryManualApproved,
|
'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 (askForFriendPromotions != null)
|
||||||
|
'ask_for_friend_promotions': askForFriendPromotions,
|
||||||
if (mediaSendCounter != null) 'media_send_counter': mediaSendCounter,
|
if (mediaSendCounter != null) 'media_send_counter': mediaSendCounter,
|
||||||
if (mediaReceivedCounter != null)
|
if (mediaReceivedCounter != null)
|
||||||
'media_received_counter': mediaReceivedCounter,
|
'media_received_counter': mediaReceivedCounter,
|
||||||
|
|
@ -1023,8 +1190,11 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
Value<DateTime>? createdAt,
|
Value<DateTime>? createdAt,
|
||||||
Value<Uint8List?>? userDiscoveryVersion,
|
Value<Uint8List?>? userDiscoveryVersion,
|
||||||
Value<bool>? userDiscoveryExcluded,
|
Value<bool>? userDiscoveryExcluded,
|
||||||
Value<bool?>? askForFriendPromotions,
|
|
||||||
Value<bool?>? userDiscoveryManualApproved,
|
Value<bool?>? userDiscoveryManualApproved,
|
||||||
|
Value<bool>? recoveryIsTrustedFriend,
|
||||||
|
Value<DateTime?>? recoveryLastHeartbeat,
|
||||||
|
Value<Uint8List?>? recoverySecretShare,
|
||||||
|
Value<bool?>? askForFriendPromotions,
|
||||||
Value<int>? mediaSendCounter,
|
Value<int>? mediaSendCounter,
|
||||||
Value<int>? mediaReceivedCounter,
|
Value<int>? mediaReceivedCounter,
|
||||||
}) {
|
}) {
|
||||||
|
|
@ -1045,10 +1215,15 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
userDiscoveryVersion: userDiscoveryVersion ?? this.userDiscoveryVersion,
|
userDiscoveryVersion: userDiscoveryVersion ?? this.userDiscoveryVersion,
|
||||||
userDiscoveryExcluded:
|
userDiscoveryExcluded:
|
||||||
userDiscoveryExcluded ?? this.userDiscoveryExcluded,
|
userDiscoveryExcluded ?? this.userDiscoveryExcluded,
|
||||||
askForFriendPromotions:
|
|
||||||
askForFriendPromotions ?? this.askForFriendPromotions,
|
|
||||||
userDiscoveryManualApproved:
|
userDiscoveryManualApproved:
|
||||||
userDiscoveryManualApproved ?? this.userDiscoveryManualApproved,
|
userDiscoveryManualApproved ?? this.userDiscoveryManualApproved,
|
||||||
|
recoveryIsTrustedFriend:
|
||||||
|
recoveryIsTrustedFriend ?? this.recoveryIsTrustedFriend,
|
||||||
|
recoveryLastHeartbeat:
|
||||||
|
recoveryLastHeartbeat ?? this.recoveryLastHeartbeat,
|
||||||
|
recoverySecretShare: recoverySecretShare ?? this.recoverySecretShare,
|
||||||
|
askForFriendPromotions:
|
||||||
|
askForFriendPromotions ?? this.askForFriendPromotions,
|
||||||
mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter,
|
mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter,
|
||||||
mediaReceivedCounter: mediaReceivedCounter ?? this.mediaReceivedCounter,
|
mediaReceivedCounter: mediaReceivedCounter ?? this.mediaReceivedCounter,
|
||||||
);
|
);
|
||||||
|
|
@ -1108,16 +1283,31 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
userDiscoveryExcluded.value,
|
userDiscoveryExcluded.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (askForFriendPromotions.present) {
|
|
||||||
map['ask_for_friend_promotions'] = Variable<bool>(
|
|
||||||
askForFriendPromotions.value,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (userDiscoveryManualApproved.present) {
|
if (userDiscoveryManualApproved.present) {
|
||||||
map['user_discovery_manual_approved'] = Variable<bool>(
|
map['user_discovery_manual_approved'] = Variable<bool>(
|
||||||
userDiscoveryManualApproved.value,
|
userDiscoveryManualApproved.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (recoveryIsTrustedFriend.present) {
|
||||||
|
map['recovery_is_trusted_friend'] = Variable<bool>(
|
||||||
|
recoveryIsTrustedFriend.value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (recoveryLastHeartbeat.present) {
|
||||||
|
map['recovery_last_heartbeat'] = Variable<DateTime>(
|
||||||
|
recoveryLastHeartbeat.value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (recoverySecretShare.present) {
|
||||||
|
map['recovery_secret_share'] = Variable<Uint8List>(
|
||||||
|
recoverySecretShare.value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (askForFriendPromotions.present) {
|
||||||
|
map['ask_for_friend_promotions'] = Variable<bool>(
|
||||||
|
askForFriendPromotions.value,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (mediaSendCounter.present) {
|
if (mediaSendCounter.present) {
|
||||||
map['media_send_counter'] = Variable<int>(mediaSendCounter.value);
|
map['media_send_counter'] = Variable<int>(mediaSendCounter.value);
|
||||||
}
|
}
|
||||||
|
|
@ -1145,8 +1335,11 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
..write('createdAt: $createdAt, ')
|
..write('createdAt: $createdAt, ')
|
||||||
..write('userDiscoveryVersion: $userDiscoveryVersion, ')
|
..write('userDiscoveryVersion: $userDiscoveryVersion, ')
|
||||||
..write('userDiscoveryExcluded: $userDiscoveryExcluded, ')
|
..write('userDiscoveryExcluded: $userDiscoveryExcluded, ')
|
||||||
..write('askForFriendPromotions: $askForFriendPromotions, ')
|
|
||||||
..write('userDiscoveryManualApproved: $userDiscoveryManualApproved, ')
|
..write('userDiscoveryManualApproved: $userDiscoveryManualApproved, ')
|
||||||
|
..write('recoveryIsTrustedFriend: $recoveryIsTrustedFriend, ')
|
||||||
|
..write('recoveryLastHeartbeat: $recoveryLastHeartbeat, ')
|
||||||
|
..write('recoverySecretShare: $recoverySecretShare, ')
|
||||||
|
..write('askForFriendPromotions: $askForFriendPromotions, ')
|
||||||
..write('mediaSendCounter: $mediaSendCounter, ')
|
..write('mediaSendCounter: $mediaSendCounter, ')
|
||||||
..write('mediaReceivedCounter: $mediaReceivedCounter')
|
..write('mediaReceivedCounter: $mediaReceivedCounter')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
|
|
@ -12924,8 +13117,11 @@ typedef $$ContactsTableCreateCompanionBuilder =
|
||||||
Value<DateTime> createdAt,
|
Value<DateTime> createdAt,
|
||||||
Value<Uint8List?> userDiscoveryVersion,
|
Value<Uint8List?> userDiscoveryVersion,
|
||||||
Value<bool> userDiscoveryExcluded,
|
Value<bool> userDiscoveryExcluded,
|
||||||
Value<bool?> askForFriendPromotions,
|
|
||||||
Value<bool?> userDiscoveryManualApproved,
|
Value<bool?> userDiscoveryManualApproved,
|
||||||
|
Value<bool> recoveryIsTrustedFriend,
|
||||||
|
Value<DateTime?> recoveryLastHeartbeat,
|
||||||
|
Value<Uint8List?> recoverySecretShare,
|
||||||
|
Value<bool?> askForFriendPromotions,
|
||||||
Value<int> mediaSendCounter,
|
Value<int> mediaSendCounter,
|
||||||
Value<int> mediaReceivedCounter,
|
Value<int> mediaReceivedCounter,
|
||||||
});
|
});
|
||||||
|
|
@ -12946,8 +13142,11 @@ typedef $$ContactsTableUpdateCompanionBuilder =
|
||||||
Value<DateTime> createdAt,
|
Value<DateTime> createdAt,
|
||||||
Value<Uint8List?> userDiscoveryVersion,
|
Value<Uint8List?> userDiscoveryVersion,
|
||||||
Value<bool> userDiscoveryExcluded,
|
Value<bool> userDiscoveryExcluded,
|
||||||
Value<bool?> askForFriendPromotions,
|
|
||||||
Value<bool?> userDiscoveryManualApproved,
|
Value<bool?> userDiscoveryManualApproved,
|
||||||
|
Value<bool> recoveryIsTrustedFriend,
|
||||||
|
Value<DateTime?> recoveryLastHeartbeat,
|
||||||
|
Value<Uint8List?> recoverySecretShare,
|
||||||
|
Value<bool?> askForFriendPromotions,
|
||||||
Value<int> mediaSendCounter,
|
Value<int> mediaSendCounter,
|
||||||
Value<int> mediaReceivedCounter,
|
Value<int> mediaReceivedCounter,
|
||||||
});
|
});
|
||||||
|
|
@ -13306,13 +13505,28 @@ class $$ContactsTableFilterComposer
|
||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
ColumnFilters<bool> get askForFriendPromotions => $composableBuilder(
|
ColumnFilters<bool> get userDiscoveryManualApproved => $composableBuilder(
|
||||||
column: $table.askForFriendPromotions,
|
column: $table.userDiscoveryManualApproved,
|
||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
ColumnFilters<bool> get userDiscoveryManualApproved => $composableBuilder(
|
ColumnFilters<bool> get recoveryIsTrustedFriend => $composableBuilder(
|
||||||
column: $table.userDiscoveryManualApproved,
|
column: $table.recoveryIsTrustedFriend,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<DateTime> get recoveryLastHeartbeat => $composableBuilder(
|
||||||
|
column: $table.recoveryLastHeartbeat,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<Uint8List> get recoverySecretShare => $composableBuilder(
|
||||||
|
column: $table.recoverySecretShare,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<bool> get askForFriendPromotions => $composableBuilder(
|
||||||
|
column: $table.askForFriendPromotions,
|
||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -13694,13 +13908,28 @@ class $$ContactsTableOrderingComposer
|
||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
ColumnOrderings<bool> get askForFriendPromotions => $composableBuilder(
|
ColumnOrderings<bool> get userDiscoveryManualApproved => $composableBuilder(
|
||||||
column: $table.askForFriendPromotions,
|
column: $table.userDiscoveryManualApproved,
|
||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
ColumnOrderings<bool> get userDiscoveryManualApproved => $composableBuilder(
|
ColumnOrderings<bool> get recoveryIsTrustedFriend => $composableBuilder(
|
||||||
column: $table.userDiscoveryManualApproved,
|
column: $table.recoveryIsTrustedFriend,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<DateTime> get recoveryLastHeartbeat => $composableBuilder(
|
||||||
|
column: $table.recoveryLastHeartbeat,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<Uint8List> get recoverySecretShare => $composableBuilder(
|
||||||
|
column: $table.recoverySecretShare,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<bool> get askForFriendPromotions => $composableBuilder(
|
||||||
|
column: $table.askForFriendPromotions,
|
||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -13783,13 +14012,28 @@ class $$ContactsTableAnnotationComposer
|
||||||
builder: (column) => column,
|
builder: (column) => column,
|
||||||
);
|
);
|
||||||
|
|
||||||
GeneratedColumn<bool> get askForFriendPromotions => $composableBuilder(
|
GeneratedColumn<bool> get userDiscoveryManualApproved => $composableBuilder(
|
||||||
column: $table.askForFriendPromotions,
|
column: $table.userDiscoveryManualApproved,
|
||||||
builder: (column) => column,
|
builder: (column) => column,
|
||||||
);
|
);
|
||||||
|
|
||||||
GeneratedColumn<bool> get userDiscoveryManualApproved => $composableBuilder(
|
GeneratedColumn<bool> get recoveryIsTrustedFriend => $composableBuilder(
|
||||||
column: $table.userDiscoveryManualApproved,
|
column: $table.recoveryIsTrustedFriend,
|
||||||
|
builder: (column) => column,
|
||||||
|
);
|
||||||
|
|
||||||
|
GeneratedColumn<DateTime> get recoveryLastHeartbeat => $composableBuilder(
|
||||||
|
column: $table.recoveryLastHeartbeat,
|
||||||
|
builder: (column) => column,
|
||||||
|
);
|
||||||
|
|
||||||
|
GeneratedColumn<Uint8List> get recoverySecretShare => $composableBuilder(
|
||||||
|
column: $table.recoverySecretShare,
|
||||||
|
builder: (column) => column,
|
||||||
|
);
|
||||||
|
|
||||||
|
GeneratedColumn<bool> get askForFriendPromotions => $composableBuilder(
|
||||||
|
column: $table.askForFriendPromotions,
|
||||||
builder: (column) => column,
|
builder: (column) => column,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -14147,8 +14391,11 @@ class $$ContactsTableTableManager
|
||||||
Value<DateTime> createdAt = const Value.absent(),
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
Value<Uint8List?> userDiscoveryVersion = const Value.absent(),
|
Value<Uint8List?> userDiscoveryVersion = const Value.absent(),
|
||||||
Value<bool> userDiscoveryExcluded = const Value.absent(),
|
Value<bool> userDiscoveryExcluded = const Value.absent(),
|
||||||
Value<bool?> askForFriendPromotions = const Value.absent(),
|
|
||||||
Value<bool?> userDiscoveryManualApproved = const Value.absent(),
|
Value<bool?> userDiscoveryManualApproved = const Value.absent(),
|
||||||
|
Value<bool> recoveryIsTrustedFriend = const Value.absent(),
|
||||||
|
Value<DateTime?> recoveryLastHeartbeat = const Value.absent(),
|
||||||
|
Value<Uint8List?> recoverySecretShare = const Value.absent(),
|
||||||
|
Value<bool?> askForFriendPromotions = const Value.absent(),
|
||||||
Value<int> mediaSendCounter = const Value.absent(),
|
Value<int> mediaSendCounter = const Value.absent(),
|
||||||
Value<int> mediaReceivedCounter = const Value.absent(),
|
Value<int> mediaReceivedCounter = const Value.absent(),
|
||||||
}) => ContactsCompanion(
|
}) => ContactsCompanion(
|
||||||
|
|
@ -14167,8 +14414,11 @@ class $$ContactsTableTableManager
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
userDiscoveryVersion: userDiscoveryVersion,
|
userDiscoveryVersion: userDiscoveryVersion,
|
||||||
userDiscoveryExcluded: userDiscoveryExcluded,
|
userDiscoveryExcluded: userDiscoveryExcluded,
|
||||||
askForFriendPromotions: askForFriendPromotions,
|
|
||||||
userDiscoveryManualApproved: userDiscoveryManualApproved,
|
userDiscoveryManualApproved: userDiscoveryManualApproved,
|
||||||
|
recoveryIsTrustedFriend: recoveryIsTrustedFriend,
|
||||||
|
recoveryLastHeartbeat: recoveryLastHeartbeat,
|
||||||
|
recoverySecretShare: recoverySecretShare,
|
||||||
|
askForFriendPromotions: askForFriendPromotions,
|
||||||
mediaSendCounter: mediaSendCounter,
|
mediaSendCounter: mediaSendCounter,
|
||||||
mediaReceivedCounter: mediaReceivedCounter,
|
mediaReceivedCounter: mediaReceivedCounter,
|
||||||
),
|
),
|
||||||
|
|
@ -14189,8 +14439,11 @@ class $$ContactsTableTableManager
|
||||||
Value<DateTime> createdAt = const Value.absent(),
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
Value<Uint8List?> userDiscoveryVersion = const Value.absent(),
|
Value<Uint8List?> userDiscoveryVersion = const Value.absent(),
|
||||||
Value<bool> userDiscoveryExcluded = const Value.absent(),
|
Value<bool> userDiscoveryExcluded = const Value.absent(),
|
||||||
Value<bool?> askForFriendPromotions = const Value.absent(),
|
|
||||||
Value<bool?> userDiscoveryManualApproved = const Value.absent(),
|
Value<bool?> userDiscoveryManualApproved = const Value.absent(),
|
||||||
|
Value<bool> recoveryIsTrustedFriend = const Value.absent(),
|
||||||
|
Value<DateTime?> recoveryLastHeartbeat = const Value.absent(),
|
||||||
|
Value<Uint8List?> recoverySecretShare = const Value.absent(),
|
||||||
|
Value<bool?> askForFriendPromotions = const Value.absent(),
|
||||||
Value<int> mediaSendCounter = const Value.absent(),
|
Value<int> mediaSendCounter = const Value.absent(),
|
||||||
Value<int> mediaReceivedCounter = const Value.absent(),
|
Value<int> mediaReceivedCounter = const Value.absent(),
|
||||||
}) => ContactsCompanion.insert(
|
}) => ContactsCompanion.insert(
|
||||||
|
|
@ -14209,8 +14462,11 @@ class $$ContactsTableTableManager
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
userDiscoveryVersion: userDiscoveryVersion,
|
userDiscoveryVersion: userDiscoveryVersion,
|
||||||
userDiscoveryExcluded: userDiscoveryExcluded,
|
userDiscoveryExcluded: userDiscoveryExcluded,
|
||||||
askForFriendPromotions: askForFriendPromotions,
|
|
||||||
userDiscoveryManualApproved: userDiscoveryManualApproved,
|
userDiscoveryManualApproved: userDiscoveryManualApproved,
|
||||||
|
recoveryIsTrustedFriend: recoveryIsTrustedFriend,
|
||||||
|
recoveryLastHeartbeat: recoveryLastHeartbeat,
|
||||||
|
recoverySecretShare: recoverySecretShare,
|
||||||
|
askForFriendPromotions: askForFriendPromotions,
|
||||||
mediaSendCounter: mediaSendCounter,
|
mediaSendCounter: mediaSendCounter,
|
||||||
mediaReceivedCounter: mediaReceivedCounter,
|
mediaReceivedCounter: mediaReceivedCounter,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -10001,6 +10001,542 @@ i1.GeneratedColumn<int> _column_248(String aliasedName) =>
|
||||||
type: i1.DriftSqlType.int,
|
type: i1.DriftSqlType.int,
|
||||||
$customConstraints: 'NULL REFERENCES contacts(user_id)ON DELETE CASCADE',
|
$customConstraints: 'NULL REFERENCES contacts(user_id)ON DELETE CASCADE',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final class Schema20 extends i0.VersionedSchema {
|
||||||
|
Schema20({required super.database}) : super(version: 20);
|
||||||
|
@override
|
||||||
|
late final List<i1.DatabaseSchemaEntity> 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 Shape55 contacts = Shape55(
|
||||||
|
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_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 Shape55 extends i0.VersionedTable {
|
||||||
|
Shape55({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get userId =>
|
||||||
|
columnsByName['user_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get username =>
|
||||||
|
columnsByName['username']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get displayName =>
|
||||||
|
columnsByName['display_name']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get nickName =>
|
||||||
|
columnsByName['nick_name']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> get avatarSvgCompressed =>
|
||||||
|
columnsByName['avatar_svg_compressed']!
|
||||||
|
as i1.GeneratedColumn<i2.Uint8List>;
|
||||||
|
i1.GeneratedColumn<int> get senderProfileCounter =>
|
||||||
|
columnsByName['sender_profile_counter']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get accepted =>
|
||||||
|
columnsByName['accepted']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get deletedByUser =>
|
||||||
|
columnsByName['deleted_by_user']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get requested =>
|
||||||
|
columnsByName['requested']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get blocked =>
|
||||||
|
columnsByName['blocked']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get verified =>
|
||||||
|
columnsByName['verified']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get accountDeleted =>
|
||||||
|
columnsByName['account_deleted']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> get userDiscoveryVersion =>
|
||||||
|
columnsByName['user_discovery_version']!
|
||||||
|
as i1.GeneratedColumn<i2.Uint8List>;
|
||||||
|
i1.GeneratedColumn<int> get userDiscoveryExcluded =>
|
||||||
|
columnsByName['user_discovery_excluded']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get userDiscoveryManualApproved =>
|
||||||
|
columnsByName['user_discovery_manual_approved']!
|
||||||
|
as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get recoveryIsTrustedFriend =>
|
||||||
|
columnsByName['recovery_is_trusted_friend']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get recoveryLastHeartbeat =>
|
||||||
|
columnsByName['recovery_last_heartbeat']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> get recoverySecretShare =>
|
||||||
|
columnsByName['recovery_secret_share']!
|
||||||
|
as i1.GeneratedColumn<i2.Uint8List>;
|
||||||
|
i1.GeneratedColumn<int> get askForFriendPromotions =>
|
||||||
|
columnsByName['ask_for_friend_promotions']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get mediaSendCounter =>
|
||||||
|
columnsByName['media_send_counter']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get mediaReceivedCounter =>
|
||||||
|
columnsByName['media_received_counter']! as i1.GeneratedColumn<int>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_249(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>(
|
||||||
|
'recovery_is_trusted_friend',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i1.DriftSqlType.int,
|
||||||
|
$customConstraints:
|
||||||
|
'NOT NULL DEFAULT 0 CHECK (recovery_is_trusted_friend IN (0, 1))',
|
||||||
|
defaultValue: const i1.CustomExpression('0'),
|
||||||
|
);
|
||||||
|
i1.GeneratedColumn<int> _column_250(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>(
|
||||||
|
'recovery_last_heartbeat',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: i1.DriftSqlType.int,
|
||||||
|
$customConstraints: 'NULL',
|
||||||
|
);
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> _column_251(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<i2.Uint8List>(
|
||||||
|
'recovery_secret_share',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: i1.DriftSqlType.blob,
|
||||||
|
$customConstraints: 'NULL',
|
||||||
|
);
|
||||||
i0.MigrationStepWithVersion migrationSteps({
|
i0.MigrationStepWithVersion migrationSteps({
|
||||||
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||||
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
||||||
|
|
@ -10020,6 +10556,7 @@ i0.MigrationStepWithVersion migrationSteps({
|
||||||
required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17,
|
required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17,
|
||||||
required Future<void> Function(i1.Migrator m, Schema18 schema) from17To18,
|
required Future<void> Function(i1.Migrator m, Schema18 schema) from17To18,
|
||||||
required Future<void> Function(i1.Migrator m, Schema19 schema) from18To19,
|
required Future<void> Function(i1.Migrator m, Schema19 schema) from18To19,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema20 schema) from19To20,
|
||||||
}) {
|
}) {
|
||||||
return (currentVersion, database) async {
|
return (currentVersion, database) async {
|
||||||
switch (currentVersion) {
|
switch (currentVersion) {
|
||||||
|
|
@ -10113,6 +10650,11 @@ i0.MigrationStepWithVersion migrationSteps({
|
||||||
final migrator = i1.Migrator(database, schema);
|
final migrator = i1.Migrator(database, schema);
|
||||||
await from18To19(migrator, schema);
|
await from18To19(migrator, schema);
|
||||||
return 19;
|
return 19;
|
||||||
|
case 19:
|
||||||
|
final schema = Schema20(database: database);
|
||||||
|
final migrator = i1.Migrator(database, schema);
|
||||||
|
await from19To20(migrator, schema);
|
||||||
|
return 20;
|
||||||
default:
|
default:
|
||||||
throw ArgumentError.value('Unknown migration from $currentVersion');
|
throw ArgumentError.value('Unknown migration from $currentVersion');
|
||||||
}
|
}
|
||||||
|
|
@ -10138,6 +10680,7 @@ i1.OnUpgrade stepByStep({
|
||||||
required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17,
|
required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17,
|
||||||
required Future<void> Function(i1.Migrator m, Schema18 schema) from17To18,
|
required Future<void> Function(i1.Migrator m, Schema18 schema) from17To18,
|
||||||
required Future<void> Function(i1.Migrator m, Schema19 schema) from18To19,
|
required Future<void> Function(i1.Migrator m, Schema19 schema) from18To19,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema20 schema) from19To20,
|
||||||
}) => i0.VersionedSchema.stepByStepHelper(
|
}) => i0.VersionedSchema.stepByStepHelper(
|
||||||
step: migrationSteps(
|
step: migrationSteps(
|
||||||
from1To2: from1To2,
|
from1To2: from1To2,
|
||||||
|
|
@ -10158,5 +10701,6 @@ i1.OnUpgrade stepByStep({
|
||||||
from16To17: from16To17,
|
from16To17: from16To17,
|
||||||
from17To18: from17To18,
|
from17To18: from17To18,
|
||||||
from18To19: from18To19,
|
from18To19: from18To19,
|
||||||
|
from19To20: from19To20,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,7 @@ class PasswordLessRecovery {
|
||||||
this.pinSeed,
|
this.pinSeed,
|
||||||
this.pinUnlockToken,
|
this.pinUnlockToken,
|
||||||
this.threshold,
|
this.threshold,
|
||||||
|
this.lastHeartbeat,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory PasswordLessRecovery.fromJson(Map<String, dynamic> json) =>
|
factory PasswordLessRecovery.fromJson(Map<String, dynamic> json) =>
|
||||||
|
|
@ -222,6 +223,7 @@ class PasswordLessRecovery {
|
||||||
String? pinSeed;
|
String? pinSeed;
|
||||||
String? pinUnlockToken;
|
String? pinUnlockToken;
|
||||||
int? threshold;
|
int? threshold;
|
||||||
|
DateTime? lastHeartbeat;
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$PasswordLessRecoveryToJson(this);
|
Map<String, dynamic> toJson() => _$PasswordLessRecoveryToJson(this);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -245,16 +245,20 @@ PasswordLessRecovery _$PasswordLessRecoveryFromJson(
|
||||||
Map<String, dynamic> json,
|
Map<String, dynamic> json,
|
||||||
) => PasswordLessRecovery(
|
) => PasswordLessRecovery(
|
||||||
email: json['email'] as String?,
|
email: json['email'] as String?,
|
||||||
pinSeed: json['pin_seed'] as String?,
|
pinSeed: json['pinSeed'] as String?,
|
||||||
pinUnlockToken: json['pin_unlock_token'] as String?,
|
pinUnlockToken: json['pinUnlockToken'] as String?,
|
||||||
threshold: (json['threshold'] as num?)?.toInt(),
|
threshold: (json['threshold'] as num?)?.toInt(),
|
||||||
|
lastHeartbeat: json['lastHeartbeat'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['lastHeartbeat'] as String),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$PasswordLessRecoveryToJson(
|
Map<String, dynamic> _$PasswordLessRecoveryToJson(
|
||||||
PasswordLessRecovery instance,
|
PasswordLessRecovery instance,
|
||||||
) => <String, dynamic>{
|
) => <String, dynamic>{
|
||||||
'email': instance.email,
|
'email': instance.email,
|
||||||
'pin_seed': instance.pinSeed,
|
'pinSeed': instance.pinSeed,
|
||||||
'pin_unlock_token': instance.pinUnlockToken,
|
'pinUnlockToken': instance.pinUnlockToken,
|
||||||
'threshold': instance.threshold,
|
'threshold': instance.threshold,
|
||||||
|
'lastHeartbeat': instance.lastHeartbeat?.toIso8601String(),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,670 @@
|
||||||
|
// This is a generated file - do not edit.
|
||||||
|
//
|
||||||
|
// Generated from types.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<RecoveryRequest>(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<EncryptedEnvelope>(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<TrustedFriendShare_User>(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<TrustedFriendShare_User>(1, _omitFieldNames ? '' : 'trustedFriend',
|
||||||
|
subBuilder: TrustedFriendShare_User.create)
|
||||||
|
..aOM<TrustedFriendShare_User>(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<TrustedFriendShare>(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SharedSecretData_SecondFactorPin extends $pb.GeneratedMessage {
|
||||||
|
factory SharedSecretData_SecondFactorPin({
|
||||||
|
$core.List<$core.int>? unlockToken,
|
||||||
|
$core.List<$core.int>? pinSeed,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (unlockToken != null) result.unlockToken = unlockToken;
|
||||||
|
if (pinSeed != null) result.pinSeed = pinSeed;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedSecretData_SecondFactorPin._();
|
||||||
|
|
||||||
|
factory SharedSecretData_SecondFactorPin.fromBuffer(
|
||||||
|
$core.List<$core.int> data,
|
||||||
|
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(data, registry);
|
||||||
|
factory SharedSecretData_SecondFactorPin.fromJson($core.String json,
|
||||||
|
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromJson(json, registry);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
|
||||||
|
_omitMessageNames ? '' : 'SharedSecretData.SecondFactorPin',
|
||||||
|
package: const $pb.PackageName(
|
||||||
|
_omitMessageNames ? '' : 'passwordless_recovery'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..a<$core.List<$core.int>>(
|
||||||
|
1, _omitFieldNames ? '' : 'unlockToken', $pb.PbFieldType.OY)
|
||||||
|
..a<$core.List<$core.int>>(
|
||||||
|
2, _omitFieldNames ? '' : 'pinSeed', $pb.PbFieldType.OY)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||||
|
SharedSecretData_SecondFactorPin clone() => deepCopy();
|
||||||
|
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||||
|
SharedSecretData_SecondFactorPin copyWith(
|
||||||
|
void Function(SharedSecretData_SecondFactorPin) updates) =>
|
||||||
|
super.copyWith(
|
||||||
|
(message) => updates(message as SharedSecretData_SecondFactorPin))
|
||||||
|
as SharedSecretData_SecondFactorPin;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static SharedSecretData_SecondFactorPin create() =>
|
||||||
|
SharedSecretData_SecondFactorPin._();
|
||||||
|
@$core.override
|
||||||
|
SharedSecretData_SecondFactorPin createEmptyInstance() => create();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static SharedSecretData_SecondFactorPin getDefault() => _defaultInstance ??=
|
||||||
|
$pb.GeneratedMessage.$_defaultFor<SharedSecretData_SecondFactorPin>(
|
||||||
|
create);
|
||||||
|
static SharedSecretData_SecondFactorPin? _defaultInstance;
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.List<$core.int> get unlockToken => $_getN(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set unlockToken($core.List<$core.int> value) => $_setBytes(0, value);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.bool hasUnlockToken() => $_has(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
void clearUnlockToken() => $_clearField(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.
|
||||||
|
@$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);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SharedSecretData_SecondFactorMail extends $pb.GeneratedMessage {
|
||||||
|
factory SharedSecretData_SecondFactorMail() => create();
|
||||||
|
|
||||||
|
SharedSecretData_SecondFactorMail._();
|
||||||
|
|
||||||
|
factory SharedSecretData_SecondFactorMail.fromBuffer(
|
||||||
|
$core.List<$core.int> data,
|
||||||
|
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(data, registry);
|
||||||
|
factory SharedSecretData_SecondFactorMail.fromJson($core.String json,
|
||||||
|
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromJson(json, registry);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
|
||||||
|
_omitMessageNames ? '' : 'SharedSecretData.SecondFactorMail',
|
||||||
|
package: const $pb.PackageName(
|
||||||
|
_omitMessageNames ? '' : 'passwordless_recovery'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||||
|
SharedSecretData_SecondFactorMail clone() => deepCopy();
|
||||||
|
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||||
|
SharedSecretData_SecondFactorMail copyWith(
|
||||||
|
void Function(SharedSecretData_SecondFactorMail) updates) =>
|
||||||
|
super.copyWith((message) =>
|
||||||
|
updates(message as SharedSecretData_SecondFactorMail))
|
||||||
|
as SharedSecretData_SecondFactorMail;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static SharedSecretData_SecondFactorMail create() =>
|
||||||
|
SharedSecretData_SecondFactorMail._();
|
||||||
|
@$core.override
|
||||||
|
SharedSecretData_SecondFactorMail createEmptyInstance() => create();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static SharedSecretData_SecondFactorMail getDefault() => _defaultInstance ??=
|
||||||
|
$pb.GeneratedMessage.$_defaultFor<SharedSecretData_SecondFactorMail>(
|
||||||
|
create);
|
||||||
|
static SharedSecretData_SecondFactorMail? _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// After received all shares this is decrypted by the user restoring its own
|
||||||
|
class SharedSecretData extends $pb.GeneratedMessage {
|
||||||
|
factory SharedSecretData({
|
||||||
|
RecoveryData? recoveryData,
|
||||||
|
SharedSecretData_SecondFactorMail? secondFactorMail,
|
||||||
|
SharedSecretData_SecondFactorPin? secondFactorPin,
|
||||||
|
$core.List<$core.int>? recoveryDataEncrypted,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (recoveryData != null) result.recoveryData = recoveryData;
|
||||||
|
if (secondFactorMail != null) result.secondFactorMail = secondFactorMail;
|
||||||
|
if (secondFactorPin != null) result.secondFactorPin = secondFactorPin;
|
||||||
|
if (recoveryDataEncrypted != null)
|
||||||
|
result.recoveryDataEncrypted = recoveryDataEncrypted;
|
||||||
|
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)
|
||||||
|
..aOM<RecoveryData>(1, _omitFieldNames ? '' : 'recoveryData',
|
||||||
|
subBuilder: RecoveryData.create)
|
||||||
|
..aOM<SharedSecretData_SecondFactorMail>(
|
||||||
|
2, _omitFieldNames ? '' : 'secondFactorMail',
|
||||||
|
subBuilder: SharedSecretData_SecondFactorMail.create)
|
||||||
|
..aOM<SharedSecretData_SecondFactorPin>(
|
||||||
|
3, _omitFieldNames ? '' : 'secondFactorPin',
|
||||||
|
subBuilder: SharedSecretData_SecondFactorPin.create)
|
||||||
|
..a<$core.List<$core.int>>(
|
||||||
|
4, _omitFieldNames ? '' : 'recoveryDataEncrypted', $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<SharedSecretData>(create);
|
||||||
|
static SharedSecretData? _defaultInstance;
|
||||||
|
|
||||||
|
/// No second factor was selected
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
RecoveryData get recoveryData => $_getN(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set recoveryData(RecoveryData value) => $_setField(1, value);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.bool hasRecoveryData() => $_has(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
void clearRecoveryData() => $_clearField(1);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
RecoveryData ensureRecoveryData() => $_ensure(0);
|
||||||
|
|
||||||
|
/// Server has
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
SharedSecretData_SecondFactorMail get secondFactorMail => $_getN(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
set secondFactorMail(SharedSecretData_SecondFactorMail value) =>
|
||||||
|
$_setField(2, value);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.bool hasSecondFactorMail() => $_has(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
void clearSecondFactorMail() => $_clearField(2);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
SharedSecretData_SecondFactorMail ensureSecondFactorMail() => $_ensure(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
SharedSecretData_SecondFactorPin get secondFactorPin => $_getN(2);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
set secondFactorPin(SharedSecretData_SecondFactorPin value) =>
|
||||||
|
$_setField(3, value);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.bool hasSecondFactorPin() => $_has(2);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
void clearSecondFactorPin() => $_clearField(3);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
SharedSecretData_SecondFactorPin ensureSecondFactorPin() => $_ensure(2);
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$core.List<$core.int> get recoveryDataEncrypted => $_getN(3);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
set recoveryDataEncrypted($core.List<$core.int> value) =>
|
||||||
|
$_setBytes(3, value);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$core.bool hasRecoveryDataEncrypted() => $_has(3);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
void clearRecoveryDataEncrypted() => $_clearField(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
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<RecoveryData>(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
const $core.bool _omitFieldNames =
|
||||||
|
$core.bool.fromEnvironment('protobuf.omit_field_names');
|
||||||
|
const $core.bool _omitMessageNames =
|
||||||
|
$core.bool.fromEnvironment('protobuf.omit_message_names');
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
// This is a generated file - do not edit.
|
||||||
|
//
|
||||||
|
// Generated from types.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
|
||||||
|
|
@ -0,0 +1,195 @@
|
||||||
|
// This is a generated file - do not edit.
|
||||||
|
//
|
||||||
|
// Generated from types.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 sharedSecretDataDescriptor instead')
|
||||||
|
const SharedSecretData$json = {
|
||||||
|
'1': 'SharedSecretData',
|
||||||
|
'2': [
|
||||||
|
{
|
||||||
|
'1': 'recovery_data',
|
||||||
|
'3': 1,
|
||||||
|
'4': 1,
|
||||||
|
'5': 11,
|
||||||
|
'6': '.passwordless_recovery.RecoveryData',
|
||||||
|
'9': 0,
|
||||||
|
'10': 'recoveryData',
|
||||||
|
'17': true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'1': 'second_factor_mail',
|
||||||
|
'3': 2,
|
||||||
|
'4': 1,
|
||||||
|
'5': 11,
|
||||||
|
'6': '.passwordless_recovery.SharedSecretData.SecondFactorMail',
|
||||||
|
'9': 1,
|
||||||
|
'10': 'secondFactorMail',
|
||||||
|
'17': true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'1': 'second_factor_pin',
|
||||||
|
'3': 3,
|
||||||
|
'4': 1,
|
||||||
|
'5': 11,
|
||||||
|
'6': '.passwordless_recovery.SharedSecretData.SecondFactorPin',
|
||||||
|
'9': 2,
|
||||||
|
'10': 'secondFactorPin',
|
||||||
|
'17': true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'1': 'recovery_data_encrypted',
|
||||||
|
'3': 4,
|
||||||
|
'4': 1,
|
||||||
|
'5': 12,
|
||||||
|
'9': 3,
|
||||||
|
'10': 'recoveryDataEncrypted',
|
||||||
|
'17': true
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'3': [
|
||||||
|
SharedSecretData_SecondFactorPin$json,
|
||||||
|
SharedSecretData_SecondFactorMail$json
|
||||||
|
],
|
||||||
|
'8': [
|
||||||
|
{'1': '_recovery_data'},
|
||||||
|
{'1': '_second_factor_mail'},
|
||||||
|
{'1': '_second_factor_pin'},
|
||||||
|
{'1': '_recovery_data_encrypted'},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
@$core.Deprecated('Use sharedSecretDataDescriptor instead')
|
||||||
|
const SharedSecretData_SecondFactorPin$json = {
|
||||||
|
'1': 'SecondFactorPin',
|
||||||
|
'2': [
|
||||||
|
{'1': 'unlock_token', '3': 1, '4': 1, '5': 12, '10': 'unlockToken'},
|
||||||
|
{'1': 'pin_seed', '3': 2, '4': 1, '5': 12, '10': 'pinSeed'},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
@$core.Deprecated('Use sharedSecretDataDescriptor instead')
|
||||||
|
const SharedSecretData_SecondFactorMail$json = {
|
||||||
|
'1': 'SecondFactorMail',
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Descriptor for `SharedSecretData`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
|
final $typed_data.Uint8List sharedSecretDataDescriptor = $convert.base64Decode(
|
||||||
|
'ChBTaGFyZWRTZWNyZXREYXRhEk0KDXJlY292ZXJ5X2RhdGEYASABKAsyIy5wYXNzd29yZGxlc3'
|
||||||
|
'NfcmVjb3ZlcnkuUmVjb3ZlcnlEYXRhSABSDHJlY292ZXJ5RGF0YYgBARJrChJzZWNvbmRfZmFj'
|
||||||
|
'dG9yX21haWwYAiABKAsyOC5wYXNzd29yZGxlc3NfcmVjb3ZlcnkuU2hhcmVkU2VjcmV0RGF0YS'
|
||||||
|
'5TZWNvbmRGYWN0b3JNYWlsSAFSEHNlY29uZEZhY3Rvck1haWyIAQESaAoRc2Vjb25kX2ZhY3Rv'
|
||||||
|
'cl9waW4YAyABKAsyNy5wYXNzd29yZGxlc3NfcmVjb3ZlcnkuU2hhcmVkU2VjcmV0RGF0YS5TZW'
|
||||||
|
'NvbmRGYWN0b3JQaW5IAlIPc2Vjb25kRmFjdG9yUGluiAEBEjsKF3JlY292ZXJ5X2RhdGFfZW5j'
|
||||||
|
'cnlwdGVkGAQgASgMSANSFXJlY292ZXJ5RGF0YUVuY3J5cHRlZIgBARpPCg9TZWNvbmRGYWN0b3'
|
||||||
|
'JQaW4SIQoMdW5sb2NrX3Rva2VuGAEgASgMUgt1bmxvY2tUb2tlbhIZCghwaW5fc2VlZBgCIAEo'
|
||||||
|
'DFIHcGluU2VlZBoSChBTZWNvbmRGYWN0b3JNYWlsQhAKDl9yZWNvdmVyeV9kYXRhQhUKE19zZW'
|
||||||
|
'NvbmRfZmFjdG9yX21haWxCFAoSX3NlY29uZF9mYWN0b3JfcGluQhoKGF9yZWNvdmVyeV9kYXRh'
|
||||||
|
'X2VuY3J5cHRlZA==');
|
||||||
|
|
||||||
|
@$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');
|
||||||
|
|
@ -85,12 +85,9 @@ final routerProvider = GoRouter(
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: 'media_viewer',
|
path: 'media_viewer',
|
||||||
pageBuilder: (context, state) {
|
builder: (context, state) {
|
||||||
final group = state.extra! as Group;
|
final group = state.extra! as Group;
|
||||||
return MediaViewerView.buildPage(
|
return MediaViewerView(group);
|
||||||
key: state.pageKey,
|
|
||||||
group: group,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,114 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert' show base64Encode, utf8;
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
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:twonly/locator.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/utils/log.dart';
|
import 'package:twonly/src/utils/log.dart';
|
||||||
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
|
enum SecondFactorType { none, pin, email }
|
||||||
|
|
||||||
class PasswordlessRecoveryService {
|
class PasswordlessRecoveryService {
|
||||||
static Future<bool> enablePasswordlessRecovery({
|
static Future<bool> enablePasswordlessRecovery({
|
||||||
required List<int> trustedFriendIds,
|
required List<int> trustedFriendIds,
|
||||||
required String secondFactorType,
|
required SecondFactorType secondFactorType,
|
||||||
required String secondFactorValue,
|
required String secondFactorValue,
|
||||||
required int threshold,
|
required int threshold,
|
||||||
}) async {
|
}) async {
|
||||||
|
await twonlyDB.contactsDao.resetRecoveryDataForAllContacts();
|
||||||
|
|
||||||
|
// 2. Update the user model configuration
|
||||||
|
|
||||||
|
final config = PasswordLessRecovery();
|
||||||
|
|
||||||
|
final serverKey = getRandomUint8List(32);
|
||||||
|
Uint8List? protectedEmailServerKey;
|
||||||
|
Uint8List? pinUnlockToken;
|
||||||
|
Uint8List? protectedPin;
|
||||||
|
|
||||||
|
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(),
|
||||||
|
);
|
||||||
|
|
||||||
|
protectedEmailServerKey = EncryptedEnvelope(
|
||||||
|
encryptedData: secretBox.cipherText,
|
||||||
|
// iv: secretBox.nonce,
|
||||||
|
mac: secretBox.mac.bytes,
|
||||||
|
).writeToBuffer();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
final scrypt = Scrypt(
|
||||||
|
cost: 65536,
|
||||||
|
salt: pinSeed,
|
||||||
|
);
|
||||||
|
|
||||||
|
final key = scrypt.convert(utf8.encode(secondFactorValue)).bytes;
|
||||||
|
protectedPin = key.sublist(0, 32);
|
||||||
|
|
||||||
|
case SecondFactorType.none:
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Use the second factor and generate the shares...
|
||||||
|
|
||||||
|
// Generate the shares, and store them in the contacrs.table.
|
||||||
|
|
||||||
Log.info('Enabling passwordless recovery with:');
|
Log.info('Enabling passwordless recovery with:');
|
||||||
Log.info(' - Trusted Friends: $trustedFriendIds');
|
Log.info(' - Trusted Friends: $trustedFriendIds');
|
||||||
Log.info(' - Second Factor Type: $secondFactorType');
|
Log.info(' - Second Factor Type: $secondFactorType');
|
||||||
Log.info(' - Second Factor Value: $secondFactorValue');
|
Log.info(' - Second Factor Value: $secondFactorValue');
|
||||||
Log.info(' - Threshold: $threshold');
|
Log.info(' - Threshold: $threshold');
|
||||||
|
|
||||||
// Simulate network delay
|
// Use the serverKey to protect the recovery_data_encrypted
|
||||||
await Future.delayed(const Duration(milliseconds: 1000));
|
|
||||||
|
// 4. Send the data to the server:
|
||||||
|
|
||||||
|
// to th server
|
||||||
|
// protectedPin, pinUnlockToken, protectedEmailServerKey;
|
||||||
|
|
||||||
|
// 5. send to the contacts / implement the heartbeat check, and notify the user in case the hearbeath shows that to few users are active...
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,8 +104,8 @@ class _MyInputState extends State<MyInput> with SingleTickerProviderStateMixin {
|
||||||
: Colors.black.withValues(alpha: 0.05);
|
: Colors.black.withValues(alpha: 0.05);
|
||||||
|
|
||||||
final inputBorderColor = isDark
|
final inputBorderColor = isDark
|
||||||
? Colors.white.withValues(alpha: 0.15)
|
? Colors.white.withValues(alpha: 0.05)
|
||||||
: Colors.black.withValues(alpha: 0.15);
|
: Colors.black.withValues(alpha: 0.05);
|
||||||
|
|
||||||
final inputHintColor = isDark
|
final inputHintColor = isDark
|
||||||
? Colors.white.withValues(alpha: 0.5)
|
? Colors.white.withValues(alpha: 0.5)
|
||||||
|
|
@ -162,7 +162,7 @@ class _MyInputState extends State<MyInput> with SingleTickerProviderStateMixin {
|
||||||
autofocus: widget.autofocus,
|
autofocus: widget.autofocus,
|
||||||
obscureText: widget.obscureText,
|
obscureText: widget.obscureText,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: widget.dense ? 16 : 18,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: isDark ? Colors.white : Colors.black87,
|
color: isDark ? Colors.white : Colors.black87,
|
||||||
),
|
),
|
||||||
|
|
@ -171,40 +171,41 @@ class _MyInputState extends State<MyInput> with SingleTickerProviderStateMixin {
|
||||||
hintText: widget.hintText,
|
hintText: widget.hintText,
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(
|
||||||
color: inputHintColor,
|
color: inputHintColor,
|
||||||
|
fontSize: widget.dense ? 16 : 18,
|
||||||
),
|
),
|
||||||
filled: true,
|
filled: true,
|
||||||
fillColor: inputFillColor,
|
fillColor: inputFillColor,
|
||||||
contentPadding: EdgeInsets.symmetric(
|
contentPadding: EdgeInsets.symmetric(
|
||||||
vertical: widget.dense ? 14 : 18,
|
vertical: widget.dense ? 13 : 18,
|
||||||
horizontal: 24,
|
horizontal: widget.dense ? 13 : 24,
|
||||||
),
|
),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(18),
|
borderRadius: BorderRadius.circular(widget.dense ? 12 : 18),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: inputBorderColor,
|
color: inputBorderColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(18),
|
borderRadius: BorderRadius.circular(widget.dense ? 12 : 18),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: inputBorderColor,
|
color: inputBorderColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(18),
|
borderRadius: BorderRadius.circular(widget.dense ? 12 : 18),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: isDark ? Colors.white : Colors.black87,
|
color: isDark ? Colors.white : Colors.black87,
|
||||||
width: 2,
|
width: 2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
errorBorder: OutlineInputBorder(
|
errorBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(18),
|
borderRadius: BorderRadius.circular(widget.dense ? 12 : 18),
|
||||||
borderSide: const BorderSide(
|
borderSide: const BorderSide(
|
||||||
color: Colors.redAccent,
|
color: Colors.redAccent,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
focusedErrorBorder: OutlineInputBorder(
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(18),
|
borderRadius: BorderRadius.circular(widget.dense ? 12 : 18),
|
||||||
borderSide: const BorderSide(
|
borderSide: const BorderSide(
|
||||||
color: Colors.redAccent,
|
color: Colors.redAccent,
|
||||||
width: 2,
|
width: 2,
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import 'package:twonly/src/services/api/mediafiles/download.api.dart'
|
||||||
as received;
|
as received;
|
||||||
import 'package:twonly/src/services/api/messages.api.dart';
|
import 'package:twonly/src/services/api/messages.api.dart';
|
||||||
import 'package:twonly/src/services/mediafiles/mediafile.service.dart';
|
import 'package:twonly/src/services/mediafiles/mediafile.service.dart';
|
||||||
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/visual/elements/better_text.element.dart';
|
import 'package:twonly/src/visual/elements/better_text.element.dart';
|
||||||
import 'package:twonly/src/visual/themes/colors.dart';
|
import 'package:twonly/src/visual/themes/colors.dart';
|
||||||
import 'package:twonly/src/visual/views/chats/chat_messages_components/entries/common.dart';
|
import 'package:twonly/src/visual/views/chats/chat_messages_components/entries/common.dart';
|
||||||
|
|
@ -93,12 +94,8 @@ class _ChatMediaEntryState extends State<ChatMediaEntry> {
|
||||||
if ((widget.mediaService.mediaFile.downloadState == DownloadState.ready) &&
|
if ((widget.mediaService.mediaFile.downloadState == DownloadState.ready) &&
|
||||||
widget.message.openedAt == null) {
|
widget.message.openedAt == null) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
await Navigator.push(
|
await context.navPush(
|
||||||
context,
|
MediaViewerView(widget.group, initialMessage: widget.message),
|
||||||
MediaViewerView.buildPage<void>(
|
|
||||||
group: widget.group,
|
|
||||||
initialMessage: widget.message,
|
|
||||||
).createRoute(context),
|
|
||||||
);
|
);
|
||||||
} else if (widget.mediaService.mediaFile.downloadState ==
|
} else if (widget.mediaService.mediaFile.downloadState ==
|
||||||
DownloadState.pending) {
|
DownloadState.pending) {
|
||||||
|
|
|
||||||
|
|
@ -42,31 +42,6 @@ class MediaViewerView extends StatefulWidget {
|
||||||
final Group group;
|
final Group group;
|
||||||
|
|
||||||
final Message? initialMessage;
|
final Message? initialMessage;
|
||||||
|
|
||||||
static Page<T> buildPage<T>({
|
|
||||||
required Group group,
|
|
||||||
LocalKey? key,
|
|
||||||
Message? initialMessage,
|
|
||||||
}) {
|
|
||||||
return CustomTransitionPage<T>(
|
|
||||||
key: key,
|
|
||||||
opaque: false,
|
|
||||||
barrierColor: Colors.transparent,
|
|
||||||
transitionDuration: const Duration(milliseconds: 250),
|
|
||||||
reverseTransitionDuration: const Duration(milliseconds: 250),
|
|
||||||
child: MediaViewerView(
|
|
||||||
group,
|
|
||||||
initialMessage: initialMessage,
|
|
||||||
),
|
|
||||||
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
|
||||||
return FadeTransition(
|
|
||||||
opacity: animation,
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<MediaViewerView> createState() => _MediaViewerViewState();
|
State<MediaViewerView> createState() => _MediaViewerViewState();
|
||||||
}
|
}
|
||||||
|
|
@ -167,14 +142,6 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
||||||
_backdropOpacityNotifier.value = linearFraction * linearFraction;
|
_backdropOpacityNotifier.value = linearFraction * linearFraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onPageSnapped(int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
if (mounted) {
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _disposeVideoController() {
|
void _disposeVideoController() {
|
||||||
final listener = _videoListener;
|
final listener = _videoListener;
|
||||||
final controller = videoController;
|
final controller = videoController;
|
||||||
|
|
@ -725,254 +692,227 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
body: ValueListenableBuilder<double>(
|
body: SafeArea(
|
||||||
valueListenable: _backdropOpacityNotifier,
|
child: Stack(
|
||||||
builder: (context, opacity, child) {
|
fit: StackFit.expand,
|
||||||
final baseColor = isDarkMode(context) ? Colors.black : Colors.white;
|
|
||||||
return ColoredBox(
|
|
||||||
color: baseColor.withValues(alpha: opacity),
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: PageView(
|
|
||||||
controller: _verticalPager,
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
physics: _isZoomed
|
|
||||||
? const NeverScrollableScrollPhysics()
|
|
||||||
: const BouncingScrollPhysics(
|
|
||||||
parent: AlwaysScrollableScrollPhysics(),
|
|
||||||
),
|
|
||||||
onPageChanged: _onPageSnapped,
|
|
||||||
children: [
|
children: [
|
||||||
const SizedBox.expand(),
|
if (_showDownloadingLoader) _loader(),
|
||||||
SafeArea(
|
if ((currentMedia != null || videoController != null) &&
|
||||||
child: Stack(
|
(canBeSeenUntil == null || progress.value >= 0))
|
||||||
fit: StackFit.expand,
|
GestureDetector(
|
||||||
children: [
|
onTap: onTap,
|
||||||
if (_showDownloadingLoader) _loader(),
|
onDoubleTap: (videoController == null) ? null : onTap,
|
||||||
if ((currentMedia != null || videoController != null) &&
|
child: MediaViewSizingHelper(
|
||||||
(canBeSeenUntil == null || progress.value >= 0))
|
bottomNavigation: bottomNavigation(),
|
||||||
GestureDetector(
|
requiredHeight: 55,
|
||||||
onTap: onTap,
|
child: Stack(
|
||||||
onDoubleTap: (videoController == null) ? null : onTap,
|
children: [
|
||||||
child: MediaViewSizingHelper(
|
if (videoController != null)
|
||||||
bottomNavigation: bottomNavigation(),
|
Positioned.fill(
|
||||||
requiredHeight: 55,
|
child: PhotoView.customChild(
|
||||||
child: Stack(
|
initialScale: PhotoViewComputedScale.contained,
|
||||||
children: [
|
minScale: PhotoViewComputedScale.contained,
|
||||||
if (videoController != null)
|
backgroundDecoration: const BoxDecoration(
|
||||||
Positioned.fill(
|
color: Colors.transparent,
|
||||||
child: PhotoView.customChild(
|
|
||||||
initialScale:
|
|
||||||
PhotoViewComputedScale.contained,
|
|
||||||
minScale: PhotoViewComputedScale.contained,
|
|
||||||
backgroundDecoration: const BoxDecoration(
|
|
||||||
color: Colors.transparent,
|
|
||||||
),
|
|
||||||
scaleStateChangedCallback: (state) {
|
|
||||||
final zoomed =
|
|
||||||
state != PhotoViewScaleState.initial;
|
|
||||||
if (_isZoomed != zoomed) {
|
|
||||||
setState(() {
|
|
||||||
_isZoomed = zoomed;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: VideoPlayer(
|
|
||||||
videoController!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else if (currentMedia != null &&
|
|
||||||
(currentMedia!.mediaFile.type ==
|
|
||||||
MediaType.image ||
|
|
||||||
currentMedia!.mediaFile.type ==
|
|
||||||
MediaType.gif))
|
|
||||||
Positioned.fill(
|
|
||||||
child: PhotoView(
|
|
||||||
imageProvider: FileImage(
|
|
||||||
currentMedia!.tempPath,
|
|
||||||
),
|
|
||||||
loadingBuilder: (context, event) => _loader(),
|
|
||||||
backgroundDecoration: const BoxDecoration(
|
|
||||||
color: Colors.transparent,
|
|
||||||
),
|
|
||||||
initialScale:
|
|
||||||
PhotoViewComputedScale.contained,
|
|
||||||
minScale: PhotoViewComputedScale.contained,
|
|
||||||
scaleStateChangedCallback: (state) {
|
|
||||||
final zoomed =
|
|
||||||
state != PhotoViewScaleState.initial;
|
|
||||||
if (_isZoomed != zoomed) {
|
|
||||||
setState(() {
|
|
||||||
_isZoomed = zoomed;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
errorBuilder: (context, error, stackTrace) {
|
|
||||||
return const Center(
|
|
||||||
child: Icon(
|
|
||||||
Icons.broken_image_outlined,
|
|
||||||
color: Colors.white38,
|
|
||||||
size: 64,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (displayTwonlyPresent)
|
|
||||||
Positioned.fill(
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () => loadCurrentMediaFile(showTwonly: true),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Lottie.asset(
|
|
||||||
'assets/animations/present.lottie.lottie',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Container(
|
scaleStateChangedCallback: (state) {
|
||||||
padding: const EdgeInsets.only(bottom: 200),
|
final zoomed =
|
||||||
child: Text(
|
state != PhotoViewScaleState.initial;
|
||||||
context.lang.mediaViewerTwonlyTapToOpen,
|
if (_isZoomed != zoomed) {
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (currentMedia != null &&
|
|
||||||
currentMedia?.mediaFile.downloadState !=
|
|
||||||
DownloadState.ready)
|
|
||||||
Positioned.fill(child: _loader()),
|
|
||||||
if (canBeSeenUntil != null || progress.value >= 0)
|
|
||||||
Positioned(
|
|
||||||
right: 20,
|
|
||||||
top: 27,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 20,
|
|
||||||
height: 20,
|
|
||||||
child: ValueListenableBuilder<double>(
|
|
||||||
valueListenable: progress,
|
|
||||||
builder: (context, value, child) {
|
|
||||||
return CircularProgressIndicator(
|
|
||||||
value: value,
|
|
||||||
strokeWidth: 2,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
top: 10,
|
|
||||||
left: showSendTextMessageInput ? 0 : null,
|
|
||||||
right: showSendTextMessageInput ? 0 : 15,
|
|
||||||
child: Text(
|
|
||||||
_currentMediaSender,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: showSendTextMessageInput ? 24 : 14,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: showSendTextMessageInput
|
|
||||||
? null
|
|
||||||
: const Color.fromARGB(255, 126, 126, 126),
|
|
||||||
shadows: const [
|
|
||||||
Shadow(
|
|
||||||
color: Color.fromARGB(122, 0, 0, 0),
|
|
||||||
blurRadius: 5,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (showSendTextMessageInput)
|
|
||||||
Positioned(
|
|
||||||
bottom: 0,
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
child: Container(
|
|
||||||
color: context.color.surface,
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
bottom: 10,
|
|
||||||
left: 20,
|
|
||||||
right: 20,
|
|
||||||
top: 10,
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: MyInput(
|
|
||||||
dense: true,
|
|
||||||
autofocus: true,
|
|
||||||
controller: textMessageController,
|
|
||||||
hintText: context.lang.chatListDetailInput,
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
onSubmitted: (value) {
|
|
||||||
setState(() {
|
|
||||||
showSendTextMessageInput = false;
|
|
||||||
showShortReactions = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
MyIconButton(
|
|
||||||
icon: const FaIcon(
|
|
||||||
FontAwesomeIcons.solidPaperPlane,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
if (textMessageController.text.isNotEmpty) {
|
|
||||||
await insertAndSendTextMessage(
|
|
||||||
widget.group.groupId,
|
|
||||||
textMessageController.text,
|
|
||||||
currentMessage!.messageId,
|
|
||||||
);
|
|
||||||
textMessageController.clear();
|
|
||||||
}
|
|
||||||
setState(() {
|
setState(() {
|
||||||
showSendTextMessageInput = false;
|
_isZoomed = zoomed;
|
||||||
showShortReactions = false;
|
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
},
|
||||||
|
child: VideoPlayer(
|
||||||
|
videoController!,
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
|
)
|
||||||
|
else if (currentMedia != null &&
|
||||||
|
(currentMedia!.mediaFile.type == MediaType.image ||
|
||||||
|
currentMedia!.mediaFile.type == MediaType.gif))
|
||||||
|
Positioned.fill(
|
||||||
|
child: PhotoView(
|
||||||
|
imageProvider: FileImage(
|
||||||
|
currentMedia!.tempPath,
|
||||||
|
),
|
||||||
|
loadingBuilder: (context, event) => _loader(),
|
||||||
|
backgroundDecoration: const BoxDecoration(
|
||||||
|
color: Colors.transparent,
|
||||||
|
),
|
||||||
|
initialScale: PhotoViewComputedScale.contained,
|
||||||
|
minScale: PhotoViewComputedScale.contained,
|
||||||
|
scaleStateChangedCallback: (state) {
|
||||||
|
final zoomed =
|
||||||
|
state != PhotoViewScaleState.initial;
|
||||||
|
if (_isZoomed != zoomed) {
|
||||||
|
setState(() {
|
||||||
|
_isZoomed = zoomed;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
return const Center(
|
||||||
|
child: Icon(
|
||||||
|
Icons.broken_image_outlined,
|
||||||
|
color: Colors.white38,
|
||||||
|
size: 64,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (displayTwonlyPresent)
|
||||||
|
Positioned.fill(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => loadCurrentMediaFile(showTwonly: true),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Lottie.asset(
|
||||||
|
'assets/animations/present.lottie.lottie',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
Container(
|
||||||
if (currentMessage != null)
|
padding: const EdgeInsets.only(bottom: 200),
|
||||||
AdditionalMessageContent(currentMessage!),
|
child: Text(
|
||||||
if (currentMedia != null)
|
context.lang.mediaViewerTwonlyTapToOpen,
|
||||||
ReactionButtons(
|
),
|
||||||
show: showShortReactions,
|
),
|
||||||
textInputFocused: showSendTextMessageInput,
|
],
|
||||||
mediaViewerDistanceFromBottom:
|
|
||||||
mediaViewerDistanceFromBottom,
|
|
||||||
groupId: widget.group.groupId,
|
|
||||||
messageId: currentMessage!.messageId,
|
|
||||||
emojiKey: emojiKey,
|
|
||||||
hide: () {
|
|
||||||
setState(() {
|
|
||||||
showShortReactions = false;
|
|
||||||
showSendTextMessageInput = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Positioned.fill(
|
|
||||||
child: EmojiFloatWidget(key: emojiKey),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
|
if (currentMedia != null &&
|
||||||
|
currentMedia?.mediaFile.downloadState != DownloadState.ready)
|
||||||
|
Positioned.fill(child: _loader()),
|
||||||
|
if (canBeSeenUntil != null || progress.value >= 0)
|
||||||
|
Positioned(
|
||||||
|
right: 20,
|
||||||
|
top: 27,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
child: ValueListenableBuilder<double>(
|
||||||
|
valueListenable: progress,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return CircularProgressIndicator(
|
||||||
|
value: value,
|
||||||
|
strokeWidth: 2,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: 10,
|
||||||
|
left: showSendTextMessageInput ? 0 : null,
|
||||||
|
right: showSendTextMessageInput ? 0 : 15,
|
||||||
|
child: Text(
|
||||||
|
_currentMediaSender,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: showSendTextMessageInput ? 24 : 14,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: showSendTextMessageInput
|
||||||
|
? null
|
||||||
|
: const Color.fromARGB(255, 126, 126, 126),
|
||||||
|
shadows: const [
|
||||||
|
Shadow(
|
||||||
|
color: Color.fromARGB(122, 0, 0, 0),
|
||||||
|
blurRadius: 5,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (showSendTextMessageInput)
|
||||||
|
Positioned(
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Container(
|
||||||
|
color: context.color.surface,
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
bottom: 10,
|
||||||
|
left: 20,
|
||||||
|
right: 20,
|
||||||
|
top: 10,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: MyInput(
|
||||||
|
dense: true,
|
||||||
|
autofocus: true,
|
||||||
|
controller: textMessageController,
|
||||||
|
hintText: context.lang.chatListDetailInput,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
onSubmitted: (value) {
|
||||||
|
setState(() {
|
||||||
|
showSendTextMessageInput = false;
|
||||||
|
showShortReactions = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
MyIconButton(
|
||||||
|
icon: const FaIcon(
|
||||||
|
FontAwesomeIcons.solidPaperPlane,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
if (textMessageController.text.isNotEmpty) {
|
||||||
|
unawaited(
|
||||||
|
insertAndSendTextMessage(
|
||||||
|
widget.group.groupId,
|
||||||
|
textMessageController.text,
|
||||||
|
currentMessage!.messageId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
textMessageController.clear();
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
showSendTextMessageInput = false;
|
||||||
|
showShortReactions = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (currentMessage != null)
|
||||||
|
AdditionalMessageContent(currentMessage!),
|
||||||
|
if (currentMedia != null)
|
||||||
|
ReactionButtons(
|
||||||
|
show: showShortReactions,
|
||||||
|
textInputFocused: showSendTextMessageInput,
|
||||||
|
mediaViewerDistanceFromBottom: mediaViewerDistanceFromBottom,
|
||||||
|
groupId: widget.group.groupId,
|
||||||
|
messageId: currentMessage!.messageId,
|
||||||
|
emojiKey: emojiKey,
|
||||||
|
hide: () {
|
||||||
|
setState(() {
|
||||||
|
showShortReactions = false;
|
||||||
|
showSendTextMessageInput = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Positioned.fill(
|
||||||
|
child: EmojiFloatWidget(key: emojiKey),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:twonly/src/services/passwordless_recovery.service.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/visual/elements/my_input.element.dart';
|
import 'package:twonly/src/visual/elements/my_input.element.dart';
|
||||||
import 'package:twonly/src/visual/themes/light.dart';
|
import 'package:twonly/src/visual/themes/light.dart';
|
||||||
import 'package:twonly/src/visual/views/settings/backup/passwordless_recovery/setup.passwordless_recovery.view.dart';
|
|
||||||
|
|
||||||
class _FactorOption {
|
class _FactorOption {
|
||||||
const _FactorOption({
|
const _FactorOption({
|
||||||
|
|
@ -62,7 +62,7 @@ class SecondFactorPicker extends StatelessWidget {
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
_buildSegmentedControl(context),
|
_buildSegmentedControl(context),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
_buildInputField(),
|
_buildInputField(context),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -138,29 +138,52 @@ class SecondFactorPicker extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildInputField() {
|
Widget _buildInputField(BuildContext context) {
|
||||||
return AnimatedSwitcher(
|
return AnimatedSwitcher(
|
||||||
duration: const Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
child: switch (selected) {
|
child: Column(
|
||||||
SecondFactorType.none => const SizedBox.shrink(
|
children: switch (selected) {
|
||||||
key: ValueKey('none_input'),
|
SecondFactorType.none => [
|
||||||
),
|
const Text(
|
||||||
SecondFactorType.pin => MyInput(
|
'Without second-factor, your friends could collaborate to recover your account. Therefore, it is recommended to configure a second-factor.',
|
||||||
key: const ValueKey('pin_input'),
|
textAlign: TextAlign.center,
|
||||||
controller: pinController,
|
),
|
||||||
hintText: 'Enter PIN',
|
],
|
||||||
keyboardType: TextInputType.number,
|
SecondFactorType.pin => [
|
||||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
MyInput(
|
||||||
onChanged: (_) => onInputChanged(),
|
key: const ValueKey('pin_input'),
|
||||||
),
|
controller: pinController,
|
||||||
SecondFactorType.email => MyInput(
|
hintText: 'Enter PIN',
|
||||||
key: const ValueKey('email_input'),
|
keyboardType: TextInputType.number,
|
||||||
controller: emailController,
|
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||||
hintText: 'Enter recovery email address',
|
onChanged: (_) => onInputChanged(),
|
||||||
keyboardType: TextInputType.emailAddress,
|
),
|
||||||
onChanged: (_) => onInputChanged(),
|
],
|
||||||
),
|
SecondFactorType.email => [
|
||||||
},
|
MyInput(
|
||||||
|
key: const ValueKey('email_input'),
|
||||||
|
controller: emailController,
|
||||||
|
hintText: 'Enter recovery email address',
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
onChanged: (_) => onInputChanged(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 6),
|
||||||
|
RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
children: formattedText(
|
||||||
|
context,
|
||||||
|
'Your email address is *never stored on the server* and is only sent to it in the event of a recovery.',
|
||||||
|
),
|
||||||
|
style: TextStyle(
|
||||||
|
color: context.color.onSurface,
|
||||||
|
fontSize: 11,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:twonly/locator.dart';
|
import 'package:twonly/locator.dart';
|
||||||
|
|
@ -11,8 +14,6 @@ import 'package:twonly/src/visual/views/settings/backup/passwordless_recovery/co
|
||||||
import 'package:twonly/src/visual/views/settings/backup/passwordless_recovery/components/trusted_friends_card.comp.dart';
|
import 'package:twonly/src/visual/views/settings/backup/passwordless_recovery/components/trusted_friends_card.comp.dart';
|
||||||
import 'package:twonly/src/visual/views/shared/select_contacts.view.dart';
|
import 'package:twonly/src/visual/views/shared/select_contacts.view.dart';
|
||||||
|
|
||||||
enum SecondFactorType { none, pin, email }
|
|
||||||
|
|
||||||
class PasswordLessRecoverySetup extends StatefulWidget {
|
class PasswordLessRecoverySetup extends StatefulWidget {
|
||||||
const PasswordLessRecoverySetup({super.key});
|
const PasswordLessRecoverySetup({super.key});
|
||||||
|
|
||||||
|
|
@ -29,6 +30,49 @@ class _PasswordLessRecoverySetupState extends State<PasswordLessRecoverySetup> {
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
int _threshold = 2;
|
int _threshold = 2;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
initAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<int>> _loadVerifiedContacts() async {
|
||||||
|
final kvs = await twonlyDB.select(twonlyDB.keyVerifications).get();
|
||||||
|
final urs = await (twonlyDB.select(
|
||||||
|
twonlyDB.userDiscoveryUserRelations,
|
||||||
|
)..where((u) => u.publicKeyVerifiedTimestamp.isNotNull())).get();
|
||||||
|
|
||||||
|
return [
|
||||||
|
...kvs.map((row) => row.contactId),
|
||||||
|
...urs.map((row) => row.announcedUserId),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> initAsync() async {
|
||||||
|
final contacts = await twonlyDB.contactsDao.getAllContacts();
|
||||||
|
if (!mounted) return;
|
||||||
|
|
||||||
|
final verified = await _loadVerifiedContacts();
|
||||||
|
|
||||||
|
contacts.sortBy((c) => c.mediaSendCounter);
|
||||||
|
final verifiedContacts = contacts
|
||||||
|
.where(
|
||||||
|
(c) =>
|
||||||
|
verified.contains(c.userId) &
|
||||||
|
c.accepted &
|
||||||
|
!c.blocked &
|
||||||
|
!c.accountDeleted &
|
||||||
|
!c.deletedByUser,
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
setState(() {
|
||||||
|
_selectedContacts = verifiedContacts.sublist(
|
||||||
|
0,
|
||||||
|
min(8, verifiedContacts.length),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_pinController.dispose();
|
_pinController.dispose();
|
||||||
|
|
@ -41,10 +85,10 @@ class _PasswordLessRecoverySetupState extends State<PasswordLessRecoverySetup> {
|
||||||
int get _minThreshold => _secondFactor == SecondFactorType.none ? 4 : 2;
|
int get _minThreshold => _secondFactor == SecondFactorType.none ? 4 : 2;
|
||||||
|
|
||||||
int get _validThreshold => ThresholdPicker.clampThreshold(
|
int get _validThreshold => ThresholdPicker.clampThreshold(
|
||||||
value: _threshold,
|
value: _threshold,
|
||||||
minThreshold: _minThreshold,
|
minThreshold: _minThreshold,
|
||||||
contactCount: _selectedContacts.length,
|
contactCount: _selectedContacts.length,
|
||||||
);
|
);
|
||||||
|
|
||||||
int get _minSelectedFriends => _validThreshold + 2;
|
int get _minSelectedFriends => _validThreshold + 2;
|
||||||
|
|
||||||
|
|
@ -55,9 +99,9 @@ class _PasswordLessRecoverySetupState extends State<PasswordLessRecoverySetup> {
|
||||||
return switch (_secondFactor) {
|
return switch (_secondFactor) {
|
||||||
SecondFactorType.none => true,
|
SecondFactorType.none => true,
|
||||||
SecondFactorType.pin => _pinController.text.length >= 4,
|
SecondFactorType.pin => _pinController.text.length >= 4,
|
||||||
SecondFactorType.email =>
|
SecondFactorType.email => RegExp(
|
||||||
RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$')
|
r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$',
|
||||||
.hasMatch(_emailController.text),
|
).hasMatch(_emailController.text),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,11 +149,11 @@ class _PasswordLessRecoverySetupState extends State<PasswordLessRecoverySetup> {
|
||||||
|
|
||||||
final success =
|
final success =
|
||||||
await PasswordlessRecoveryService.enablePasswordlessRecovery(
|
await PasswordlessRecoveryService.enablePasswordlessRecovery(
|
||||||
trustedFriendIds: _selectedContacts.map((c) => c.userId).toList(),
|
trustedFriendIds: _selectedContacts.map((c) => c.userId).toList(),
|
||||||
secondFactorType: _secondFactor.name,
|
secondFactorType: _secondFactor,
|
||||||
secondFactorValue: secondFactorValue,
|
secondFactorValue: secondFactorValue,
|
||||||
threshold: _validThreshold,
|
threshold: _validThreshold,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
setState(() => _isLoading = false);
|
setState(() => _isLoading = false);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ description: "twonly, a privacy-friendly way to connect with friends through sec
|
||||||
|
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
version: 0.3.1+143
|
version: 0.3.1+145
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.11.0
|
sdk: ^3.11.0
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@ protoc --proto_path="$CLIENT_DIR" --dart_out="$GENERATED_DIR" "data.proto"
|
||||||
mkdir "$GENERATED_DIR/user_discovery/" &>/dev/null
|
mkdir "$GENERATED_DIR/user_discovery/" &>/dev/null
|
||||||
protoc --proto_path="./rust/src/user_discovery/" --dart_out="$GENERATED_DIR/user_discovery/" "types.proto"
|
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" --dart_out="$GENERATED_DIR" "push_notification.proto"
|
||||||
protoc --proto_path="$CLIENT_DIR" --swift_out="./ios/NotificationService/" "push_notification.proto"
|
protoc --proto_path="$CLIENT_DIR" --swift_out="./ios/NotificationService/" "push_notification.proto"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import 'schema_v16.dart' as v16;
|
||||||
import 'schema_v17.dart' as v17;
|
import 'schema_v17.dart' as v17;
|
||||||
import 'schema_v18.dart' as v18;
|
import 'schema_v18.dart' as v18;
|
||||||
import 'schema_v19.dart' as v19;
|
import 'schema_v19.dart' as v19;
|
||||||
|
import 'schema_v20.dart' as v20;
|
||||||
|
|
||||||
class GeneratedHelper implements SchemaInstantiationHelper {
|
class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
@override
|
@override
|
||||||
|
|
@ -66,6 +67,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
return v18.DatabaseAtV18(db);
|
return v18.DatabaseAtV18(db);
|
||||||
case 19:
|
case 19:
|
||||||
return v19.DatabaseAtV19(db);
|
return v19.DatabaseAtV19(db);
|
||||||
|
case 20:
|
||||||
|
return v20.DatabaseAtV20(db);
|
||||||
default:
|
default:
|
||||||
throw MissingSchemaException(version, versions);
|
throw MissingSchemaException(version, versions);
|
||||||
}
|
}
|
||||||
|
|
@ -91,5 +94,6 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
17,
|
17,
|
||||||
18,
|
18,
|
||||||
19,
|
19,
|
||||||
|
20,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10880
test/drift/twonly_db/generated/schema_v20.dart
Normal file
10880
test/drift/twonly_db/generated/schema_v20.dart
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue