mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-07-18 01:14:07 +00:00
send the threshold to the other user
Some checks failed
Flutter analyze & test / flutter_analyze_and_test (push) Has been cancelled
Some checks failed
Flutter analyze & test / flutter_analyze_and_test (push) Has been cancelled
This commit is contained in:
parent
991376e1d9
commit
9faa4fc49a
17 changed files with 14937 additions and 87 deletions
3137
lib/src/database/schemas/twonly_db/drift_schema_v22.json
Normal file
3137
lib/src/database/schemas/twonly_db/drift_schema_v22.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -39,6 +39,7 @@ class Contacts extends Table {
|
|||
// This is the share from the contact in case the contact has selected this user as his trusted friend.
|
||||
BlobColumn get recoveryContactsSecretShare => blob().nullable()();
|
||||
DateTimeColumn get recoveryContactsLastHeartbeat => dateTime().nullable()();
|
||||
IntColumn get recoveryContactsThreshold => integer().nullable()();
|
||||
|
||||
BoolColumn get askForFriendPromotions => boolean().nullable()();
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class TwonlyDB extends _$TwonlyDB {
|
|||
TwonlyDB.forTesting(DatabaseConnection super.connection);
|
||||
|
||||
@override
|
||||
int get schemaVersion => 21;
|
||||
int get schemaVersion => 22;
|
||||
|
||||
static QueryExecutor _openConnection() {
|
||||
final connection = driftDatabase(
|
||||
|
|
@ -269,6 +269,12 @@ class TwonlyDB extends _$TwonlyDB {
|
|||
schema.contacts.recoveryContactsLastHeartbeat,
|
||||
);
|
||||
},
|
||||
from21To22: (m, schema) async {
|
||||
await m.addColumn(
|
||||
schema.contacts,
|
||||
schema.contacts.recoveryContactsThreshold,
|
||||
);
|
||||
},
|
||||
)(m, from, to);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -274,6 +274,17 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
type: DriftSqlType.dateTime,
|
||||
requiredDuringInsert: false,
|
||||
);
|
||||
static const VerificationMeta _recoveryContactsThresholdMeta =
|
||||
const VerificationMeta('recoveryContactsThreshold');
|
||||
@override
|
||||
late final GeneratedColumn<int> recoveryContactsThreshold =
|
||||
GeneratedColumn<int>(
|
||||
'recovery_contacts_threshold',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
);
|
||||
static const VerificationMeta _askForFriendPromotionsMeta =
|
||||
const VerificationMeta('askForFriendPromotions');
|
||||
@override
|
||||
|
|
@ -334,6 +345,7 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
recoverySecretShare,
|
||||
recoveryContactsSecretShare,
|
||||
recoveryContactsLastHeartbeat,
|
||||
recoveryContactsThreshold,
|
||||
askForFriendPromotions,
|
||||
mediaSendCounter,
|
||||
mediaReceivedCounter,
|
||||
|
|
@ -517,6 +529,15 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('recovery_contacts_threshold')) {
|
||||
context.handle(
|
||||
_recoveryContactsThresholdMeta,
|
||||
recoveryContactsThreshold.isAcceptableOrUnknown(
|
||||
data['recovery_contacts_threshold']!,
|
||||
_recoveryContactsThresholdMeta,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('ask_for_friend_promotions')) {
|
||||
context.handle(
|
||||
_askForFriendPromotionsMeta,
|
||||
|
|
@ -637,6 +658,10 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
DriftSqlType.dateTime,
|
||||
data['${effectivePrefix}recovery_contacts_last_heartbeat'],
|
||||
),
|
||||
recoveryContactsThreshold: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.int,
|
||||
data['${effectivePrefix}recovery_contacts_threshold'],
|
||||
),
|
||||
askForFriendPromotions: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.bool,
|
||||
data['${effectivePrefix}ask_for_friend_promotions'],
|
||||
|
|
@ -680,6 +705,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
final Uint8List? recoverySecretShare;
|
||||
final Uint8List? recoveryContactsSecretShare;
|
||||
final DateTime? recoveryContactsLastHeartbeat;
|
||||
final int? recoveryContactsThreshold;
|
||||
final bool? askForFriendPromotions;
|
||||
final int mediaSendCounter;
|
||||
final int mediaReceivedCounter;
|
||||
|
|
@ -705,6 +731,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
this.recoverySecretShare,
|
||||
this.recoveryContactsSecretShare,
|
||||
this.recoveryContactsLastHeartbeat,
|
||||
this.recoveryContactsThreshold,
|
||||
this.askForFriendPromotions,
|
||||
required this.mediaSendCounter,
|
||||
required this.mediaReceivedCounter,
|
||||
|
|
@ -759,6 +786,11 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
recoveryContactsLastHeartbeat,
|
||||
);
|
||||
}
|
||||
if (!nullToAbsent || recoveryContactsThreshold != null) {
|
||||
map['recovery_contacts_threshold'] = Variable<int>(
|
||||
recoveryContactsThreshold,
|
||||
);
|
||||
}
|
||||
if (!nullToAbsent || askForFriendPromotions != null) {
|
||||
map['ask_for_friend_promotions'] = Variable<bool>(askForFriendPromotions);
|
||||
}
|
||||
|
|
@ -811,6 +843,10 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
recoveryContactsLastHeartbeat == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(recoveryContactsLastHeartbeat),
|
||||
recoveryContactsThreshold:
|
||||
recoveryContactsThreshold == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(recoveryContactsThreshold),
|
||||
askForFriendPromotions: askForFriendPromotions == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(askForFriendPromotions),
|
||||
|
|
@ -866,6 +902,9 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
recoveryContactsLastHeartbeat: serializer.fromJson<DateTime?>(
|
||||
json['recoveryContactsLastHeartbeat'],
|
||||
),
|
||||
recoveryContactsThreshold: serializer.fromJson<int?>(
|
||||
json['recoveryContactsThreshold'],
|
||||
),
|
||||
askForFriendPromotions: serializer.fromJson<bool?>(
|
||||
json['askForFriendPromotions'],
|
||||
),
|
||||
|
|
@ -912,6 +951,9 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
'recoveryContactsLastHeartbeat': serializer.toJson<DateTime?>(
|
||||
recoveryContactsLastHeartbeat,
|
||||
),
|
||||
'recoveryContactsThreshold': serializer.toJson<int?>(
|
||||
recoveryContactsThreshold,
|
||||
),
|
||||
'askForFriendPromotions': serializer.toJson<bool?>(
|
||||
askForFriendPromotions,
|
||||
),
|
||||
|
|
@ -942,6 +984,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
Value<Uint8List?> recoverySecretShare = const Value.absent(),
|
||||
Value<Uint8List?> recoveryContactsSecretShare = const Value.absent(),
|
||||
Value<DateTime?> recoveryContactsLastHeartbeat = const Value.absent(),
|
||||
Value<int?> recoveryContactsThreshold = const Value.absent(),
|
||||
Value<bool?> askForFriendPromotions = const Value.absent(),
|
||||
int? mediaSendCounter,
|
||||
int? mediaReceivedCounter,
|
||||
|
|
@ -982,6 +1025,9 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
recoveryContactsLastHeartbeat: recoveryContactsLastHeartbeat.present
|
||||
? recoveryContactsLastHeartbeat.value
|
||||
: this.recoveryContactsLastHeartbeat,
|
||||
recoveryContactsThreshold: recoveryContactsThreshold.present
|
||||
? recoveryContactsThreshold.value
|
||||
: this.recoveryContactsThreshold,
|
||||
askForFriendPromotions: askForFriendPromotions.present
|
||||
? askForFriendPromotions.value
|
||||
: this.askForFriendPromotions,
|
||||
|
|
@ -1037,6 +1083,9 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
recoveryContactsLastHeartbeat: data.recoveryContactsLastHeartbeat.present
|
||||
? data.recoveryContactsLastHeartbeat.value
|
||||
: this.recoveryContactsLastHeartbeat,
|
||||
recoveryContactsThreshold: data.recoveryContactsThreshold.present
|
||||
? data.recoveryContactsThreshold.value
|
||||
: this.recoveryContactsThreshold,
|
||||
askForFriendPromotions: data.askForFriendPromotions.present
|
||||
? data.askForFriendPromotions.value
|
||||
: this.askForFriendPromotions,
|
||||
|
|
@ -1075,6 +1124,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
..write(
|
||||
'recoveryContactsLastHeartbeat: $recoveryContactsLastHeartbeat, ',
|
||||
)
|
||||
..write('recoveryContactsThreshold: $recoveryContactsThreshold, ')
|
||||
..write('askForFriendPromotions: $askForFriendPromotions, ')
|
||||
..write('mediaSendCounter: $mediaSendCounter, ')
|
||||
..write('mediaReceivedCounter: $mediaReceivedCounter')
|
||||
|
|
@ -1105,6 +1155,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
$driftBlobEquality.hash(recoverySecretShare),
|
||||
$driftBlobEquality.hash(recoveryContactsSecretShare),
|
||||
recoveryContactsLastHeartbeat,
|
||||
recoveryContactsThreshold,
|
||||
askForFriendPromotions,
|
||||
mediaSendCounter,
|
||||
mediaReceivedCounter,
|
||||
|
|
@ -1148,6 +1199,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
) &&
|
||||
other.recoveryContactsLastHeartbeat ==
|
||||
this.recoveryContactsLastHeartbeat &&
|
||||
other.recoveryContactsThreshold == this.recoveryContactsThreshold &&
|
||||
other.askForFriendPromotions == this.askForFriendPromotions &&
|
||||
other.mediaSendCounter == this.mediaSendCounter &&
|
||||
other.mediaReceivedCounter == this.mediaReceivedCounter);
|
||||
|
|
@ -1175,6 +1227,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
final Value<Uint8List?> recoverySecretShare;
|
||||
final Value<Uint8List?> recoveryContactsSecretShare;
|
||||
final Value<DateTime?> recoveryContactsLastHeartbeat;
|
||||
final Value<int?> recoveryContactsThreshold;
|
||||
final Value<bool?> askForFriendPromotions;
|
||||
final Value<int> mediaSendCounter;
|
||||
final Value<int> mediaReceivedCounter;
|
||||
|
|
@ -1200,6 +1253,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
this.recoverySecretShare = const Value.absent(),
|
||||
this.recoveryContactsSecretShare = const Value.absent(),
|
||||
this.recoveryContactsLastHeartbeat = const Value.absent(),
|
||||
this.recoveryContactsThreshold = const Value.absent(),
|
||||
this.askForFriendPromotions = const Value.absent(),
|
||||
this.mediaSendCounter = const Value.absent(),
|
||||
this.mediaReceivedCounter = const Value.absent(),
|
||||
|
|
@ -1226,6 +1280,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
this.recoverySecretShare = const Value.absent(),
|
||||
this.recoveryContactsSecretShare = const Value.absent(),
|
||||
this.recoveryContactsLastHeartbeat = const Value.absent(),
|
||||
this.recoveryContactsThreshold = const Value.absent(),
|
||||
this.askForFriendPromotions = const Value.absent(),
|
||||
this.mediaSendCounter = const Value.absent(),
|
||||
this.mediaReceivedCounter = const Value.absent(),
|
||||
|
|
@ -1252,6 +1307,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
Expression<Uint8List>? recoverySecretShare,
|
||||
Expression<Uint8List>? recoveryContactsSecretShare,
|
||||
Expression<DateTime>? recoveryContactsLastHeartbeat,
|
||||
Expression<int>? recoveryContactsThreshold,
|
||||
Expression<bool>? askForFriendPromotions,
|
||||
Expression<int>? mediaSendCounter,
|
||||
Expression<int>? mediaReceivedCounter,
|
||||
|
|
@ -1288,6 +1344,8 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
'recovery_contacts_secret_share': recoveryContactsSecretShare,
|
||||
if (recoveryContactsLastHeartbeat != null)
|
||||
'recovery_contacts_last_heartbeat': recoveryContactsLastHeartbeat,
|
||||
if (recoveryContactsThreshold != null)
|
||||
'recovery_contacts_threshold': recoveryContactsThreshold,
|
||||
if (askForFriendPromotions != null)
|
||||
'ask_for_friend_promotions': askForFriendPromotions,
|
||||
if (mediaSendCounter != null) 'media_send_counter': mediaSendCounter,
|
||||
|
|
@ -1318,6 +1376,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
Value<Uint8List?>? recoverySecretShare,
|
||||
Value<Uint8List?>? recoveryContactsSecretShare,
|
||||
Value<DateTime?>? recoveryContactsLastHeartbeat,
|
||||
Value<int?>? recoveryContactsThreshold,
|
||||
Value<bool?>? askForFriendPromotions,
|
||||
Value<int>? mediaSendCounter,
|
||||
Value<int>? mediaReceivedCounter,
|
||||
|
|
@ -1350,6 +1409,8 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
recoveryContactsSecretShare ?? this.recoveryContactsSecretShare,
|
||||
recoveryContactsLastHeartbeat:
|
||||
recoveryContactsLastHeartbeat ?? this.recoveryContactsLastHeartbeat,
|
||||
recoveryContactsThreshold:
|
||||
recoveryContactsThreshold ?? this.recoveryContactsThreshold,
|
||||
askForFriendPromotions:
|
||||
askForFriendPromotions ?? this.askForFriendPromotions,
|
||||
mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter,
|
||||
|
|
@ -1441,6 +1502,11 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
recoveryContactsLastHeartbeat.value,
|
||||
);
|
||||
}
|
||||
if (recoveryContactsThreshold.present) {
|
||||
map['recovery_contacts_threshold'] = Variable<int>(
|
||||
recoveryContactsThreshold.value,
|
||||
);
|
||||
}
|
||||
if (askForFriendPromotions.present) {
|
||||
map['ask_for_friend_promotions'] = Variable<bool>(
|
||||
askForFriendPromotions.value,
|
||||
|
|
@ -1481,6 +1547,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
..write(
|
||||
'recoveryContactsLastHeartbeat: $recoveryContactsLastHeartbeat, ',
|
||||
)
|
||||
..write('recoveryContactsThreshold: $recoveryContactsThreshold, ')
|
||||
..write('askForFriendPromotions: $askForFriendPromotions, ')
|
||||
..write('mediaSendCounter: $mediaSendCounter, ')
|
||||
..write('mediaReceivedCounter: $mediaReceivedCounter')
|
||||
|
|
@ -13265,6 +13332,7 @@ typedef $$ContactsTableCreateCompanionBuilder =
|
|||
Value<Uint8List?> recoverySecretShare,
|
||||
Value<Uint8List?> recoveryContactsSecretShare,
|
||||
Value<DateTime?> recoveryContactsLastHeartbeat,
|
||||
Value<int?> recoveryContactsThreshold,
|
||||
Value<bool?> askForFriendPromotions,
|
||||
Value<int> mediaSendCounter,
|
||||
Value<int> mediaReceivedCounter,
|
||||
|
|
@ -13292,6 +13360,7 @@ typedef $$ContactsTableUpdateCompanionBuilder =
|
|||
Value<Uint8List?> recoverySecretShare,
|
||||
Value<Uint8List?> recoveryContactsSecretShare,
|
||||
Value<DateTime?> recoveryContactsLastHeartbeat,
|
||||
Value<int?> recoveryContactsThreshold,
|
||||
Value<bool?> askForFriendPromotions,
|
||||
Value<int> mediaSendCounter,
|
||||
Value<int> mediaReceivedCounter,
|
||||
|
|
@ -13683,6 +13752,11 @@ class $$ContactsTableFilterComposer
|
|||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<int> get recoveryContactsThreshold => $composableBuilder(
|
||||
column: $table.recoveryContactsThreshold,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<bool> get askForFriendPromotions => $composableBuilder(
|
||||
column: $table.askForFriendPromotions,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
|
|
@ -14098,6 +14172,11 @@ class $$ContactsTableOrderingComposer
|
|||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<int> get recoveryContactsThreshold => $composableBuilder(
|
||||
column: $table.recoveryContactsThreshold,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<bool> get askForFriendPromotions => $composableBuilder(
|
||||
column: $table.askForFriendPromotions,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
|
|
@ -14214,6 +14293,11 @@ class $$ContactsTableAnnotationComposer
|
|||
builder: (column) => column,
|
||||
);
|
||||
|
||||
GeneratedColumn<int> get recoveryContactsThreshold => $composableBuilder(
|
||||
column: $table.recoveryContactsThreshold,
|
||||
builder: (column) => column,
|
||||
);
|
||||
|
||||
GeneratedColumn<bool> get askForFriendPromotions => $composableBuilder(
|
||||
column: $table.askForFriendPromotions,
|
||||
builder: (column) => column,
|
||||
|
|
@ -14581,6 +14665,7 @@ class $$ContactsTableTableManager
|
|||
const Value.absent(),
|
||||
Value<DateTime?> recoveryContactsLastHeartbeat =
|
||||
const Value.absent(),
|
||||
Value<int?> recoveryContactsThreshold = const Value.absent(),
|
||||
Value<bool?> askForFriendPromotions = const Value.absent(),
|
||||
Value<int> mediaSendCounter = const Value.absent(),
|
||||
Value<int> mediaReceivedCounter = const Value.absent(),
|
||||
|
|
@ -14606,6 +14691,7 @@ class $$ContactsTableTableManager
|
|||
recoverySecretShare: recoverySecretShare,
|
||||
recoveryContactsSecretShare: recoveryContactsSecretShare,
|
||||
recoveryContactsLastHeartbeat: recoveryContactsLastHeartbeat,
|
||||
recoveryContactsThreshold: recoveryContactsThreshold,
|
||||
askForFriendPromotions: askForFriendPromotions,
|
||||
mediaSendCounter: mediaSendCounter,
|
||||
mediaReceivedCounter: mediaReceivedCounter,
|
||||
|
|
@ -14635,6 +14721,7 @@ class $$ContactsTableTableManager
|
|||
const Value.absent(),
|
||||
Value<DateTime?> recoveryContactsLastHeartbeat =
|
||||
const Value.absent(),
|
||||
Value<int?> recoveryContactsThreshold = const Value.absent(),
|
||||
Value<bool?> askForFriendPromotions = const Value.absent(),
|
||||
Value<int> mediaSendCounter = const Value.absent(),
|
||||
Value<int> mediaReceivedCounter = const Value.absent(),
|
||||
|
|
@ -14660,6 +14747,7 @@ class $$ContactsTableTableManager
|
|||
recoverySecretShare: recoverySecretShare,
|
||||
recoveryContactsSecretShare: recoveryContactsSecretShare,
|
||||
recoveryContactsLastHeartbeat: recoveryContactsLastHeartbeat,
|
||||
recoveryContactsThreshold: recoveryContactsThreshold,
|
||||
askForFriendPromotions: askForFriendPromotions,
|
||||
mediaSendCounter: mediaSendCounter,
|
||||
mediaReceivedCounter: mediaReceivedCounter,
|
||||
|
|
|
|||
|
|
@ -11071,6 +11071,535 @@ i1.GeneratedColumn<int> _column_253(String aliasedName) =>
|
|||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NULL',
|
||||
);
|
||||
|
||||
final class Schema22 extends i0.VersionedSchema {
|
||||
Schema22({required super.database}) : super(version: 22);
|
||||
@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 Shape57 contacts = Shape57(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'contacts',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: ['PRIMARY KEY(user_id)'],
|
||||
columns: [
|
||||
_column_106,
|
||||
_column_107,
|
||||
_column_108,
|
||||
_column_109,
|
||||
_column_110,
|
||||
_column_111,
|
||||
_column_112,
|
||||
_column_113,
|
||||
_column_114,
|
||||
_column_115,
|
||||
_column_116,
|
||||
_column_117,
|
||||
_column_118,
|
||||
_column_211,
|
||||
_column_212,
|
||||
_column_213,
|
||||
_column_249,
|
||||
_column_250,
|
||||
_column_251,
|
||||
_column_252,
|
||||
_column_253,
|
||||
_column_254,
|
||||
_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 Shape57 extends i0.VersionedTable {
|
||||
Shape57({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<i2.Uint8List> get recoveryContactsSecretShare =>
|
||||
columnsByName['recovery_contacts_secret_share']!
|
||||
as i1.GeneratedColumn<i2.Uint8List>;
|
||||
i1.GeneratedColumn<int> get recoveryContactsLastHeartbeat =>
|
||||
columnsByName['recovery_contacts_last_heartbeat']!
|
||||
as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get recoveryContactsThreshold =>
|
||||
columnsByName['recovery_contacts_threshold']! as i1.GeneratedColumn<int>;
|
||||
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_254(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'recovery_contacts_threshold',
|
||||
aliasedName,
|
||||
true,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NULL',
|
||||
);
|
||||
i0.MigrationStepWithVersion migrationSteps({
|
||||
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
||||
|
|
@ -11092,6 +11621,7 @@ i0.MigrationStepWithVersion migrationSteps({
|
|||
required Future<void> Function(i1.Migrator m, Schema19 schema) from18To19,
|
||||
required Future<void> Function(i1.Migrator m, Schema20 schema) from19To20,
|
||||
required Future<void> Function(i1.Migrator m, Schema21 schema) from20To21,
|
||||
required Future<void> Function(i1.Migrator m, Schema22 schema) from21To22,
|
||||
}) {
|
||||
return (currentVersion, database) async {
|
||||
switch (currentVersion) {
|
||||
|
|
@ -11195,6 +11725,11 @@ i0.MigrationStepWithVersion migrationSteps({
|
|||
final migrator = i1.Migrator(database, schema);
|
||||
await from20To21(migrator, schema);
|
||||
return 21;
|
||||
case 21:
|
||||
final schema = Schema22(database: database);
|
||||
final migrator = i1.Migrator(database, schema);
|
||||
await from21To22(migrator, schema);
|
||||
return 22;
|
||||
default:
|
||||
throw ArgumentError.value('Unknown migration from $currentVersion');
|
||||
}
|
||||
|
|
@ -11222,6 +11757,7 @@ i1.OnUpgrade stepByStep({
|
|||
required Future<void> Function(i1.Migrator m, Schema19 schema) from18To19,
|
||||
required Future<void> Function(i1.Migrator m, Schema20 schema) from19To20,
|
||||
required Future<void> Function(i1.Migrator m, Schema21 schema) from20To21,
|
||||
required Future<void> Function(i1.Migrator m, Schema22 schema) from21To22,
|
||||
}) => i0.VersionedSchema.stepByStepHelper(
|
||||
step: migrationSteps(
|
||||
from1To2: from1To2,
|
||||
|
|
@ -11244,5 +11780,6 @@ i1.OnUpgrade stepByStep({
|
|||
from18To19: from18To19,
|
||||
from19To20: from19To20,
|
||||
from20To21: from20To21,
|
||||
from21To22: from21To22,
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ class TwonlySafeBackup {
|
|||
|
||||
@JsonSerializable()
|
||||
class PasswordLessRecovery {
|
||||
PasswordLessRecovery();
|
||||
PasswordLessRecovery(this.threshold);
|
||||
|
||||
factory PasswordLessRecovery.fromJson(Map<String, dynamic> json) =>
|
||||
_$PasswordLessRecoveryFromJson(json);
|
||||
|
|
@ -218,6 +218,8 @@ class PasswordLessRecovery {
|
|||
|
||||
// <--
|
||||
// Data shared with trusted friends
|
||||
|
||||
int threshold;
|
||||
// Trusted friends are able to brute-force the pin -> Server delets after X tries
|
||||
List<int>? pinSeed;
|
||||
List<int>? pinUnlockToken;
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ const _$LastBackupUploadStateEnumMap = {
|
|||
|
||||
PasswordLessRecovery _$PasswordLessRecoveryFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => PasswordLessRecovery()
|
||||
) => PasswordLessRecovery((json['threshold'] as num).toInt())
|
||||
..email = json['email'] as String?
|
||||
..pinSeed = (json['pinSeed'] as List<dynamic>?)
|
||||
?.map((e) => (e as num).toInt())
|
||||
|
|
@ -269,6 +269,7 @@ Map<String, dynamic> _$PasswordLessRecoveryToJson(
|
|||
PasswordLessRecovery instance,
|
||||
) => <String, dynamic>{
|
||||
'email': instance.email,
|
||||
'threshold': instance.threshold,
|
||||
'pinSeed': instance.pinSeed,
|
||||
'pinUnlockToken': instance.pinUnlockToken,
|
||||
'encryptedServerKeyNonce': instance.encryptedServerKeyNonce,
|
||||
|
|
|
|||
|
|
@ -1843,11 +1843,13 @@ class EncryptedContent_PasswordLessRecovery extends $pb.GeneratedMessage {
|
|||
factory EncryptedContent_PasswordLessRecovery({
|
||||
$core.List<$core.int>? recoverySecretShare,
|
||||
$core.bool? delete,
|
||||
$fixnum.Int64? threshold,
|
||||
}) {
|
||||
final result = create();
|
||||
if (recoverySecretShare != null)
|
||||
result.recoverySecretShare = recoverySecretShare;
|
||||
if (delete != null) result.delete = delete;
|
||||
if (threshold != null) result.threshold = threshold;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1868,6 +1870,7 @@ class EncryptedContent_PasswordLessRecovery extends $pb.GeneratedMessage {
|
|||
1, _omitFieldNames ? '' : 'recoverySecretShare', $pb.PbFieldType.OY,
|
||||
protoName: 'recoverySecretShare')
|
||||
..aOB(2, _omitFieldNames ? '' : 'delete')
|
||||
..aInt64(3, _omitFieldNames ? '' : 'threshold')
|
||||
..hasRequiredFields = false;
|
||||
|
||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||
|
|
@ -1910,6 +1913,15 @@ class EncryptedContent_PasswordLessRecovery extends $pb.GeneratedMessage {
|
|||
$core.bool hasDelete() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearDelete() => $_clearField(2);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
$fixnum.Int64 get threshold => $_getI64(2);
|
||||
@$pb.TagNumber(3)
|
||||
set threshold($fixnum.Int64 value) => $_setInt64(2, value);
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasThreshold() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearThreshold() => $_clearField(3);
|
||||
}
|
||||
|
||||
class EncryptedContent_PasswordLessRecoveryHeartbeat
|
||||
|
|
|
|||
|
|
@ -993,6 +993,7 @@ const EncryptedContent_PasswordLessRecovery$json = {
|
|||
'17': true
|
||||
},
|
||||
{'1': 'delete', '3': 2, '4': 1, '5': 8, '10': 'delete'},
|
||||
{'1': 'threshold', '3': 3, '4': 1, '5': 3, '10': 'threshold'},
|
||||
],
|
||||
'8': [
|
||||
{'1': '_recoverySecretShare'},
|
||||
|
|
@ -1110,18 +1111,18 @@ final $typed_data.Uint8List encryptedContentDescriptor = $convert.base64Decode(
|
|||
'bmcSHQoKY3JlYXRlZF9hdBgCIAEoA1IJY3JlYXRlZEF0Gj8KFFVzZXJEaXNjb3ZlcnlSZXF1ZX'
|
||||
'N0EicKD2N1cnJlbnRfdmVyc2lvbhgBIAEoDFIOY3VycmVudFZlcnNpb24aMQoTVXNlckRpc2Nv'
|
||||
'dmVyeVVwZGF0ZRIaCghtZXNzYWdlcxgBIAMoDFIIbWVzc2FnZXMaPQoUS2V5VmVyaWZpY2F0aW'
|
||||
'9uUHJvb2YSJQoOY2FsY3VsYXRlZF9tYWMYASABKAxSDWNhbGN1bGF0ZWRNYWMafQoUUGFzc3dv'
|
||||
'cmRMZXNzUmVjb3ZlcnkSNQoTcmVjb3ZlcnlTZWNyZXRTaGFyZRgBIAEoDEgAUhNyZWNvdmVyeV'
|
||||
'NlY3JldFNoYXJliAEBEhYKBmRlbGV0ZRgCIAEoCFIGZGVsZXRlQhYKFF9yZWNvdmVyeVNlY3Jl'
|
||||
'dFNoYXJlGjMKHVBhc3N3b3JkTGVzc1JlY292ZXJ5SGVhcnRiZWF0EhIKBGhhc2gYASABKAxSBG'
|
||||
'hhc2hCCwoJX2dyb3VwX2lkQhEKD19pc19kaXJlY3RfY2hhdEIZChdfc2VuZGVyX3Byb2ZpbGVf'
|
||||
'Y291bnRlckIgCh5fc2VuZGVyX3VzZXJfZGlzY292ZXJ5X3ZlcnNpb25CHAoaX2Fza19mb3JfZn'
|
||||
'JpZW5kX3Byb21vdGlvbnNCEQoPX21lc3NhZ2VfdXBkYXRlQggKBl9tZWRpYUIPCg1fbWVkaWFf'
|
||||
'dXBkYXRlQhEKD19jb250YWN0X3VwZGF0ZUISChBfY29udGFjdF9yZXF1ZXN0Qg0KC19mbGFtZV'
|
||||
'9zeW5jQgwKCl9wdXNoX2tleXNCCwoJX3JlYWN0aW9uQg8KDV90ZXh0X21lc3NhZ2VCDwoNX2dy'
|
||||
'b3VwX2NyZWF0ZUINCgtfZ3JvdXBfam9pbkIPCg1fZ3JvdXBfdXBkYXRlQhoKGF9yZXNlbmRfZ3'
|
||||
'JvdXBfcHVibGljX2tleUIRCg9fZXJyb3JfbWVzc2FnZXNCGgoYX2FkZGl0aW9uYWxfZGF0YV9t'
|
||||
'ZXNzYWdlQhMKEV90eXBpbmdfaW5kaWNhdG9yQhkKF191c2VyX2Rpc2NvdmVyeV9yZXF1ZXN0Qh'
|
||||
'gKFl91c2VyX2Rpc2NvdmVyeV91cGRhdGVCGQoXX2tleV92ZXJpZmljYXRpb25fcHJvb2ZCGAoW'
|
||||
'X3Bhc3N3b3JkbGVzc19yZWNvdmVyeUIiCiBfcGFzc3dvcmRsZXNzX3JlY292ZXJ5X2hlYXJ0Ym'
|
||||
'VhdA==');
|
||||
'9uUHJvb2YSJQoOY2FsY3VsYXRlZF9tYWMYASABKAxSDWNhbGN1bGF0ZWRNYWMamwEKFFBhc3N3'
|
||||
'b3JkTGVzc1JlY292ZXJ5EjUKE3JlY292ZXJ5U2VjcmV0U2hhcmUYASABKAxIAFITcmVjb3Zlcn'
|
||||
'lTZWNyZXRTaGFyZYgBARIWCgZkZWxldGUYAiABKAhSBmRlbGV0ZRIcCgl0aHJlc2hvbGQYAyAB'
|
||||
'KANSCXRocmVzaG9sZEIWChRfcmVjb3ZlcnlTZWNyZXRTaGFyZRozCh1QYXNzd29yZExlc3NSZW'
|
||||
'NvdmVyeUhlYXJ0YmVhdBISCgRoYXNoGAEgASgMUgRoYXNoQgsKCV9ncm91cF9pZEIRCg9faXNf'
|
||||
'ZGlyZWN0X2NoYXRCGQoXX3NlbmRlcl9wcm9maWxlX2NvdW50ZXJCIAoeX3NlbmRlcl91c2VyX2'
|
||||
'Rpc2NvdmVyeV92ZXJzaW9uQhwKGl9hc2tfZm9yX2ZyaWVuZF9wcm9tb3Rpb25zQhEKD19tZXNz'
|
||||
'YWdlX3VwZGF0ZUIICgZfbWVkaWFCDwoNX21lZGlhX3VwZGF0ZUIRCg9fY29udGFjdF91cGRhdG'
|
||||
'VCEgoQX2NvbnRhY3RfcmVxdWVzdEINCgtfZmxhbWVfc3luY0IMCgpfcHVzaF9rZXlzQgsKCV9y'
|
||||
'ZWFjdGlvbkIPCg1fdGV4dF9tZXNzYWdlQg8KDV9ncm91cF9jcmVhdGVCDQoLX2dyb3VwX2pvaW'
|
||||
'5CDwoNX2dyb3VwX3VwZGF0ZUIaChhfcmVzZW5kX2dyb3VwX3B1YmxpY19rZXlCEQoPX2Vycm9y'
|
||||
'X21lc3NhZ2VzQhoKGF9hZGRpdGlvbmFsX2RhdGFfbWVzc2FnZUITChFfdHlwaW5nX2luZGljYX'
|
||||
'RvckIZChdfdXNlcl9kaXNjb3ZlcnlfcmVxdWVzdEIYChZfdXNlcl9kaXNjb3ZlcnlfdXBkYXRl'
|
||||
'QhkKF19rZXlfdmVyaWZpY2F0aW9uX3Byb29mQhgKFl9wYXNzd29yZGxlc3NfcmVjb3ZlcnlCIg'
|
||||
'ogX3Bhc3N3b3JkbGVzc19yZWNvdmVyeV9oZWFydGJlYXQ=');
|
||||
|
|
|
|||
|
|
@ -431,18 +431,18 @@ class RecoveryData extends $pb.GeneratedMessage {
|
|||
class SharedSecretData extends $pb.GeneratedMessage {
|
||||
factory SharedSecretData({
|
||||
$core.List<$core.int>? recoveryData,
|
||||
$core.List<$core.int>? encryptedServerKeyNonce,
|
||||
$core.List<$core.int>? pinSeed,
|
||||
$core.List<$core.int>? pinUnlockToken,
|
||||
$core.String? emailHint,
|
||||
$core.List<$core.int>? encryptedServerKeyNonce,
|
||||
}) {
|
||||
final result = create();
|
||||
if (recoveryData != null) result.recoveryData = recoveryData;
|
||||
if (encryptedServerKeyNonce != null)
|
||||
result.encryptedServerKeyNonce = encryptedServerKeyNonce;
|
||||
if (pinSeed != null) result.pinSeed = pinSeed;
|
||||
if (pinUnlockToken != null) result.pinUnlockToken = pinUnlockToken;
|
||||
if (emailHint != null) result.emailHint = emailHint;
|
||||
if (encryptedServerKeyNonce != null)
|
||||
result.encryptedServerKeyNonce = encryptedServerKeyNonce;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -463,12 +463,12 @@ class SharedSecretData extends $pb.GeneratedMessage {
|
|||
..a<$core.List<$core.int>>(
|
||||
1, _omitFieldNames ? '' : 'recoveryData', $pb.PbFieldType.OY)
|
||||
..a<$core.List<$core.int>>(
|
||||
2, _omitFieldNames ? '' : 'pinSeed', $pb.PbFieldType.OY)
|
||||
3, _omitFieldNames ? '' : 'encryptedServerKeyNonce', $pb.PbFieldType.OY)
|
||||
..a<$core.List<$core.int>>(
|
||||
3, _omitFieldNames ? '' : 'pinUnlockToken', $pb.PbFieldType.OY)
|
||||
..aOS(4, _omitFieldNames ? '' : 'emailHint')
|
||||
4, _omitFieldNames ? '' : 'pinSeed', $pb.PbFieldType.OY)
|
||||
..a<$core.List<$core.int>>(
|
||||
5, _omitFieldNames ? '' : 'encryptedServerKeyNonce', $pb.PbFieldType.OY)
|
||||
5, _omitFieldNames ? '' : 'pinUnlockToken', $pb.PbFieldType.OY)
|
||||
..aOS(6, _omitFieldNames ? '' : 'emailHint')
|
||||
..hasRequiredFields = false;
|
||||
|
||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||
|
|
@ -500,42 +500,42 @@ class SharedSecretData extends $pb.GeneratedMessage {
|
|||
@$pb.TagNumber(1)
|
||||
void clearRecoveryData() => $_clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.List<$core.int> get pinSeed => $_getN(1);
|
||||
@$pb.TagNumber(2)
|
||||
set pinSeed($core.List<$core.int> value) => $_setBytes(1, value);
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasPinSeed() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearPinSeed() => $_clearField(2);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
$core.List<$core.int> get pinUnlockToken => $_getN(2);
|
||||
$core.List<$core.int> get encryptedServerKeyNonce => $_getN(1);
|
||||
@$pb.TagNumber(3)
|
||||
set pinUnlockToken($core.List<$core.int> value) => $_setBytes(2, value);
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasPinUnlockToken() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearPinUnlockToken() => $_clearField(3);
|
||||
|
||||
@$pb.TagNumber(4)
|
||||
$core.String get emailHint => $_getSZ(3);
|
||||
@$pb.TagNumber(4)
|
||||
set emailHint($core.String value) => $_setString(3, value);
|
||||
@$pb.TagNumber(4)
|
||||
$core.bool hasEmailHint() => $_has(3);
|
||||
@$pb.TagNumber(4)
|
||||
void clearEmailHint() => $_clearField(4);
|
||||
|
||||
@$pb.TagNumber(5)
|
||||
$core.List<$core.int> get encryptedServerKeyNonce => $_getN(4);
|
||||
@$pb.TagNumber(5)
|
||||
set encryptedServerKeyNonce($core.List<$core.int> value) =>
|
||||
$_setBytes(4, value);
|
||||
$_setBytes(1, value);
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasEncryptedServerKeyNonce() => $_has(1);
|
||||
@$pb.TagNumber(3)
|
||||
void clearEncryptedServerKeyNonce() => $_clearField(3);
|
||||
|
||||
@$pb.TagNumber(4)
|
||||
$core.List<$core.int> get pinSeed => $_getN(2);
|
||||
@$pb.TagNumber(4)
|
||||
set pinSeed($core.List<$core.int> value) => $_setBytes(2, value);
|
||||
@$pb.TagNumber(4)
|
||||
$core.bool hasPinSeed() => $_has(2);
|
||||
@$pb.TagNumber(4)
|
||||
void clearPinSeed() => $_clearField(4);
|
||||
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasEncryptedServerKeyNonce() => $_has(4);
|
||||
$core.List<$core.int> get pinUnlockToken => $_getN(3);
|
||||
@$pb.TagNumber(5)
|
||||
void clearEncryptedServerKeyNonce() => $_clearField(5);
|
||||
set pinUnlockToken($core.List<$core.int> value) => $_setBytes(3, value);
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasPinUnlockToken() => $_has(3);
|
||||
@$pb.TagNumber(5)
|
||||
void clearPinUnlockToken() => $_clearField(5);
|
||||
|
||||
@$pb.TagNumber(6)
|
||||
$core.String get emailHint => $_getSZ(4);
|
||||
@$pb.TagNumber(6)
|
||||
set emailHint($core.String value) => $_setString(4, value);
|
||||
@$pb.TagNumber(6)
|
||||
$core.bool hasEmailHint() => $_has(4);
|
||||
@$pb.TagNumber(6)
|
||||
void clearEmailHint() => $_clearField(6);
|
||||
}
|
||||
|
||||
const $core.bool _omitFieldNames =
|
||||
|
|
|
|||
|
|
@ -116,55 +116,55 @@ const SharedSecretData$json = {
|
|||
'2': [
|
||||
{'1': 'recovery_data', '3': 1, '4': 1, '5': 12, '10': 'recoveryData'},
|
||||
{
|
||||
'1': 'pin_seed',
|
||||
'3': 2,
|
||||
'1': 'encrypted_server_key_nonce',
|
||||
'3': 3,
|
||||
'4': 1,
|
||||
'5': 12,
|
||||
'9': 0,
|
||||
'10': 'encryptedServerKeyNonce',
|
||||
'17': true
|
||||
},
|
||||
{
|
||||
'1': 'pin_seed',
|
||||
'3': 4,
|
||||
'4': 1,
|
||||
'5': 12,
|
||||
'9': 1,
|
||||
'10': 'pinSeed',
|
||||
'17': true
|
||||
},
|
||||
{
|
||||
'1': 'pin_unlock_token',
|
||||
'3': 3,
|
||||
'3': 5,
|
||||
'4': 1,
|
||||
'5': 12,
|
||||
'9': 1,
|
||||
'9': 2,
|
||||
'10': 'pinUnlockToken',
|
||||
'17': true
|
||||
},
|
||||
{
|
||||
'1': 'email_hint',
|
||||
'3': 4,
|
||||
'3': 6,
|
||||
'4': 1,
|
||||
'5': 9,
|
||||
'9': 2,
|
||||
'10': 'emailHint',
|
||||
'17': true
|
||||
},
|
||||
{
|
||||
'1': 'encrypted_server_key_nonce',
|
||||
'3': 5,
|
||||
'4': 1,
|
||||
'5': 12,
|
||||
'9': 3,
|
||||
'10': 'encryptedServerKeyNonce',
|
||||
'10': 'emailHint',
|
||||
'17': true
|
||||
},
|
||||
],
|
||||
'8': [
|
||||
{'1': '_encrypted_server_key_nonce'},
|
||||
{'1': '_pin_seed'},
|
||||
{'1': '_pin_unlock_token'},
|
||||
{'1': '_email_hint'},
|
||||
{'1': '_encrypted_server_key_nonce'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `SharedSecretData`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List sharedSecretDataDescriptor = $convert.base64Decode(
|
||||
'ChBTaGFyZWRTZWNyZXREYXRhEiMKDXJlY292ZXJ5X2RhdGEYASABKAxSDHJlY292ZXJ5RGF0YR'
|
||||
'IeCghwaW5fc2VlZBgCIAEoDEgAUgdwaW5TZWVkiAEBEi0KEHBpbl91bmxvY2tfdG9rZW4YAyAB'
|
||||
'KAxIAVIOcGluVW5sb2NrVG9rZW6IAQESIgoKZW1haWxfaGludBgEIAEoCUgCUgllbWFpbEhpbn'
|
||||
'SIAQESQAoaZW5jcnlwdGVkX3NlcnZlcl9rZXlfbm9uY2UYBSABKAxIA1IXZW5jcnlwdGVkU2Vy'
|
||||
'dmVyS2V5Tm9uY2WIAQFCCwoJX3Bpbl9zZWVkQhMKEV9waW5fdW5sb2NrX3Rva2VuQg0KC19lbW'
|
||||
'FpbF9oaW50Qh0KG19lbmNyeXB0ZWRfc2VydmVyX2tleV9ub25jZQ==');
|
||||
'JAChplbmNyeXB0ZWRfc2VydmVyX2tleV9ub25jZRgDIAEoDEgAUhdlbmNyeXB0ZWRTZXJ2ZXJL'
|
||||
'ZXlOb25jZYgBARIeCghwaW5fc2VlZBgEIAEoDEgBUgdwaW5TZWVkiAEBEi0KEHBpbl91bmxvY2'
|
||||
'tfdG9rZW4YBSABKAxIAlIOcGluVW5sb2NrVG9rZW6IAQESIgoKZW1haWxfaGludBgGIAEoCUgD'
|
||||
'UgllbWFpbEhpbnSIAQFCHQobX2VuY3J5cHRlZF9zZXJ2ZXJfa2V5X25vbmNlQgsKCV9waW5fc2'
|
||||
'VlZEITChFfcGluX3VubG9ja190b2tlbkINCgtfZW1haWxfaGludA==');
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ message EncryptedContent {
|
|||
message PasswordLessRecovery {
|
||||
optional bytes recoverySecretShare = 1;
|
||||
bool delete = 2;
|
||||
int64 threshold = 3;
|
||||
}
|
||||
|
||||
message PasswordLessRecoveryHeartbeat {
|
||||
|
|
|
|||
|
|
@ -58,11 +58,12 @@ message SharedSecretData {
|
|||
// The recovery data is encrypted in case a second factor was chosen.
|
||||
bytes recovery_data = 1;
|
||||
|
||||
optional bytes pin_seed = 2;
|
||||
optional bytes pin_unlock_token = 3;
|
||||
optional bytes encrypted_server_key_nonce = 3;
|
||||
|
||||
optional string email_hint = 4;
|
||||
optional bytes encrypted_server_key_nonce = 5;
|
||||
optional bytes pin_seed = 4;
|
||||
optional bytes pin_unlock_token = 5;
|
||||
|
||||
optional string email_hint = 6;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ class PasswordlessRecoveryService {
|
|||
try {
|
||||
final share = contact.recoveryContactsSecretShare;
|
||||
if (share == null) {
|
||||
Log.warn('Contact does not have a recovery share stored.');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +116,7 @@ class PasswordlessRecoveryService {
|
|||
final trustedFriendShare = TrustedFriendShare(
|
||||
trustedFriend: trustedFriend,
|
||||
shareUser: shareUser,
|
||||
threshold: 0,
|
||||
threshold: contact.recoveryContactsThreshold,
|
||||
sharedSecretData: share,
|
||||
);
|
||||
|
||||
|
|
@ -176,7 +177,7 @@ class PasswordlessRecoveryService {
|
|||
await twonlyDB.contactsDao.resetRecoveryDataForAllContacts();
|
||||
await UserService.update((u) => u.passwordLessRecovery = null);
|
||||
|
||||
final config = PasswordLessRecovery();
|
||||
final config = PasswordLessRecovery(threshold);
|
||||
final xchacha20 = Xchacha20.poly1305Aead();
|
||||
|
||||
// 2. If enabled, handle the second factor and create serverKey
|
||||
|
|
@ -417,6 +418,7 @@ class PasswordlessRecoveryService {
|
|||
passwordlessRecovery: pb.EncryptedContent_PasswordLessRecovery(
|
||||
recoverySecretShare: contact.recoverySecretShare,
|
||||
delete: false,
|
||||
threshold: Int64(config.threshold),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
@ -491,7 +493,7 @@ class PasswordlessRecoveryService {
|
|||
recoveryContactsLastHeartbeat: Value(null),
|
||||
),
|
||||
);
|
||||
} else if (msg.hasRecoverySecretShare()) {
|
||||
} else if (msg.hasRecoverySecretShare() && msg.hasThreshold()) {
|
||||
Log.info(
|
||||
'[$receiptId] Received new passwordless recovery share from contact $fromUserId',
|
||||
);
|
||||
|
|
@ -501,6 +503,7 @@ class PasswordlessRecoveryService {
|
|||
recoveryContactsSecretShare: Value(
|
||||
Uint8List.fromList(msg.recoverySecretShare),
|
||||
),
|
||||
recoveryContactsThreshold: Value(msg.threshold.toInt()),
|
||||
recoveryContactsLastHeartbeat: const Value(
|
||||
null, // this will trigger that a heartbeat will be send...
|
||||
),
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import 'schema_v18.dart' as v18;
|
|||
import 'schema_v19.dart' as v19;
|
||||
import 'schema_v20.dart' as v20;
|
||||
import 'schema_v21.dart' as v21;
|
||||
import 'schema_v22.dart' as v22;
|
||||
|
||||
class GeneratedHelper implements SchemaInstantiationHelper {
|
||||
@override
|
||||
|
|
@ -72,6 +73,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
|||
return v20.DatabaseAtV20(db);
|
||||
case 21:
|
||||
return v21.DatabaseAtV21(db);
|
||||
case 22:
|
||||
return v22.DatabaseAtV22(db);
|
||||
default:
|
||||
throw MissingSchemaException(version, versions);
|
||||
}
|
||||
|
|
@ -99,5 +102,6 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
|||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
11056
test/drift/twonly_db/generated/schema_v22.dart
Normal file
11056
test/drift/twonly_db/generated/schema_v22.dart
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -282,7 +282,7 @@ void main() {
|
|||
test(
|
||||
'triggers server registration based on lastServerHeartbeat time',
|
||||
() async {
|
||||
final config = PasswordLessRecovery()
|
||||
final config = PasswordLessRecovery(3)
|
||||
..encryptedServerKey = Uint8List.fromList([1, 2, 3])
|
||||
..pinUnlockToken = Uint8List.fromList([4, 5, 6]);
|
||||
|
||||
|
|
@ -330,7 +330,7 @@ void main() {
|
|||
test(
|
||||
'sends secret shares to trusted friends with null recoveryLastHeartbeat',
|
||||
() async {
|
||||
final config = PasswordLessRecovery()
|
||||
final config = PasswordLessRecovery(3)
|
||||
..encryptedServerKey = Uint8List.fromList([1, 2, 3])
|
||||
..pinUnlockToken = Uint8List.fromList([4, 5, 6]);
|
||||
await UserService.update((u) => u.passwordLessRecovery = config);
|
||||
|
|
@ -376,7 +376,7 @@ void main() {
|
|||
test(
|
||||
'sends heartbeat to friends who chose us as a trusted friend based on time',
|
||||
() async {
|
||||
final config = PasswordLessRecovery()
|
||||
final config = PasswordLessRecovery(3)
|
||||
..encryptedServerKey = Uint8List.fromList([1, 2, 3])
|
||||
..pinUnlockToken = Uint8List.fromList([4, 5, 6]);
|
||||
await UserService.update((u) => u.passwordLessRecovery = config);
|
||||
|
|
|
|||
Loading…
Reference in a new issue