refactor(keybackup): Update database for stored megolm keys to prepare for proper online key backup
This commit is contained in:
parent
20d72eb8d7
commit
ea59c4bd94
|
@ -71,7 +71,20 @@ class KeyManager {
|
|||
|
||||
void setInboundGroupSession(String roomId, String sessionId, String senderKey,
|
||||
Map<String, dynamic> content,
|
||||
{bool forwarded = false}) {
|
||||
{bool forwarded = false, Map<String, String> senderClaimedKeys}) {
|
||||
senderClaimedKeys ??= <String, String>{};
|
||||
if (!senderClaimedKeys.containsKey('ed25519')) {
|
||||
DeviceKeys device;
|
||||
for (final user in client.userDeviceKeys.values) {
|
||||
device = user.deviceKeys.values.firstWhere(
|
||||
(e) => e.curve25519Key == senderKey,
|
||||
orElse: () => null);
|
||||
if (device != null) {
|
||||
senderClaimedKeys['ed25519'] = device.ed25519Key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
final oldSession =
|
||||
getInboundGroupSession(roomId, sessionId, senderKey, otherRooms: false);
|
||||
if (content['algorithm'] != 'm.megolm.v1.aes-sha2') {
|
||||
|
@ -97,6 +110,8 @@ class KeyManager {
|
|||
inboundGroupSession: inboundGroupSession,
|
||||
indexes: {},
|
||||
key: client.userID,
|
||||
senderKey: senderKey,
|
||||
senderClaimedKeys: senderClaimedKeys,
|
||||
);
|
||||
final oldFirstIndex =
|
||||
oldSession?.inboundGroupSession?.first_known_index() ?? 0;
|
||||
|
@ -124,6 +139,8 @@ class KeyManager {
|
|||
inboundGroupSession.pickle(client.userID),
|
||||
json.encode(content),
|
||||
json.encode({}),
|
||||
senderKey,
|
||||
json.encode(senderClaimedKeys),
|
||||
);
|
||||
// Note to self: When adding key-backup that needs to be unawaited(), else
|
||||
// we might accidentally end up with http requests inside of the sync loop
|
||||
|
@ -139,7 +156,11 @@ class KeyManager {
|
|||
{bool otherRooms = true}) {
|
||||
if (_inboundGroupSessions.containsKey(roomId) &&
|
||||
_inboundGroupSessions[roomId].containsKey(sessionId)) {
|
||||
return _inboundGroupSessions[roomId][sessionId];
|
||||
final sess = _inboundGroupSessions[roomId][sessionId];
|
||||
if (sess.senderKey != senderKey && sess.senderKey.isNotEmpty) {
|
||||
return null;
|
||||
}
|
||||
return sess;
|
||||
}
|
||||
if (!otherRooms) {
|
||||
return null;
|
||||
|
@ -147,7 +168,11 @@ class KeyManager {
|
|||
// search if this session id is *somehow* found in another room
|
||||
for (final val in _inboundGroupSessions.values) {
|
||||
if (val.containsKey(sessionId)) {
|
||||
return val[sessionId];
|
||||
final sess = val[sessionId];
|
||||
if (sess.senderKey != senderKey && sess.senderKey.isNotEmpty) {
|
||||
return null;
|
||||
}
|
||||
return sess;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -161,7 +186,11 @@ class KeyManager {
|
|||
}
|
||||
if (_inboundGroupSessions.containsKey(roomId) &&
|
||||
_inboundGroupSessions[roomId].containsKey(sessionId)) {
|
||||
return _inboundGroupSessions[roomId][sessionId]; // nothing to do
|
||||
final sess = _inboundGroupSessions[roomId][sessionId];
|
||||
if (sess.senderKey != senderKey && sess.senderKey.isNotEmpty) {
|
||||
return null; // sender keys do not match....better not do anything
|
||||
}
|
||||
return sess; // nothing to do
|
||||
}
|
||||
final session = await client.database
|
||||
?.getDbInboundGroupSession(client.id, roomId, sessionId);
|
||||
|
@ -181,7 +210,8 @@ class KeyManager {
|
|||
_inboundGroupSessions[roomId] = <String, SessionKey>{};
|
||||
}
|
||||
final sess = SessionKey.fromDb(session, client.userID);
|
||||
if (!sess.isValid) {
|
||||
if (!sess.isValid ||
|
||||
(sess.senderKey.isNotEmpty && sess.senderKey != senderKey)) {
|
||||
return null;
|
||||
}
|
||||
_inboundGroupSessions[roomId][sessionId] = sess;
|
||||
|
@ -377,7 +407,10 @@ class KeyManager {
|
|||
decrypted['room_id'] = roomId;
|
||||
setInboundGroupSession(
|
||||
roomId, sessionId, decrypted['sender_key'], decrypted,
|
||||
forwarded: true);
|
||||
forwarded: true,
|
||||
senderClaimedKeys: decrypted['sender_claimed_keys'] != null
|
||||
? Map<String, String>.from(decrypted['sender_claimed_keys'])
|
||||
: null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -556,11 +589,20 @@ class KeyManager {
|
|||
if (device == null) {
|
||||
return; // someone we didn't send our request to replied....better ignore this
|
||||
}
|
||||
// we add the sender key to the forwarded key chain
|
||||
if (!(event.content['forwarding_curve25519_key_chain'] is List)) {
|
||||
event.content['forwarding_curve25519_key_chain'] = <String>[];
|
||||
}
|
||||
event.content['forwarding_curve25519_key_chain']
|
||||
.add(event.encryptedContent['sender_key']);
|
||||
// TODO: verify that the keys work to decrypt a message
|
||||
// alright, all checks out, let's go ahead and store this session
|
||||
setInboundGroupSession(
|
||||
request.room.id, request.sessionId, request.senderKey, event.content,
|
||||
forwarded: true);
|
||||
forwarded: true,
|
||||
senderClaimedKeys: {
|
||||
'ed25519': event.content['sender_claimed_ed25519_key'],
|
||||
});
|
||||
request.devices.removeWhere(
|
||||
(k) => k.userId == device.userId && k.deviceId == device.deviceId);
|
||||
outgoingShareRequests.remove(request.requestId);
|
||||
|
@ -659,28 +701,19 @@ class RoomKeyRequest extends ToDeviceEvent {
|
|||
var room = this.room;
|
||||
final session = await keyManager.loadInboundGroupSession(
|
||||
room.id, request.sessionId, request.senderKey);
|
||||
var forwardedKeys = <dynamic>[keyManager.encryption.identityKey];
|
||||
for (final key in session.forwardingCurve25519KeyChain) {
|
||||
forwardedKeys.add(key);
|
||||
}
|
||||
var message = session.content;
|
||||
message['forwarding_curve25519_key_chain'] = forwardedKeys;
|
||||
message['forwarding_curve25519_key_chain'] =
|
||||
List<String>.from(session.forwardingCurve25519KeyChain);
|
||||
|
||||
message['sender_key'] = request.senderKey;
|
||||
message['sender_key'] =
|
||||
(session.senderKey != null && session.senderKey.isNotEmpty)
|
||||
? session.senderKey
|
||||
: request.senderKey;
|
||||
message['sender_claimed_ed25519_key'] =
|
||||
forwardedKeys.isEmpty ? keyManager.encryption.fingerprintKey : null;
|
||||
if (message['sender_claimed_ed25519_key'] == null) {
|
||||
for (final value in keyManager.client.userDeviceKeys.values) {
|
||||
for (final key in value.deviceKeys.values) {
|
||||
if (key.curve25519Key == forwardedKeys.first) {
|
||||
message['sender_claimed_ed25519_key'] = key.ed25519Key;
|
||||
}
|
||||
}
|
||||
if (message['sender_claimed_ed25519_key'] != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
session.senderClaimedKeys['ed25519'] ??
|
||||
(session.forwardingCurve25519KeyChain.isEmpty
|
||||
? keyManager.encryption.fingerprintKey
|
||||
: null);
|
||||
message['session_key'] = session.inboundGroupSession
|
||||
.export_session(session.inboundGroupSession.first_known_index());
|
||||
// send the actual reply of the key back to the requester
|
||||
|
|
|
@ -29,23 +29,39 @@ class SessionKey {
|
|||
Map<String, int> indexes;
|
||||
olm.InboundGroupSession inboundGroupSession;
|
||||
final String key;
|
||||
List<dynamic> get forwardingCurve25519KeyChain =>
|
||||
content['forwarding_curve25519_key_chain'] ?? [];
|
||||
String get senderClaimedEd25519Key =>
|
||||
content['sender_claimed_ed25519_key'] ?? '';
|
||||
String get senderKey => content['sender_key'] ?? '';
|
||||
List<String> get forwardingCurve25519KeyChain =>
|
||||
(content['forwarding_curve25519_key_chain'] != null
|
||||
? List<String>.from(content['forwarding_curve25519_key_chain'])
|
||||
: null) ??
|
||||
<String>[];
|
||||
Map<String, String> senderClaimedKeys;
|
||||
String senderKey;
|
||||
bool get isValid => inboundGroupSession != null;
|
||||
|
||||
SessionKey({this.content, this.inboundGroupSession, this.key, this.indexes});
|
||||
SessionKey(
|
||||
{this.content,
|
||||
this.inboundGroupSession,
|
||||
this.key,
|
||||
this.indexes,
|
||||
String senderKey,
|
||||
Map<String, String> senderClaimedKeys}) {
|
||||
_setSenderKey(senderKey);
|
||||
_setSenderClaimedKeys(senderClaimedKeys);
|
||||
}
|
||||
|
||||
SessionKey.fromDb(DbInboundGroupSession dbEntry, String key) : key = key {
|
||||
final parsedContent = Event.getMapFromPayload(dbEntry.content);
|
||||
final parsedIndexes = Event.getMapFromPayload(dbEntry.indexes);
|
||||
final parsedSenderClaimedKeys =
|
||||
Event.getMapFromPayload(dbEntry.senderClaimedKeys);
|
||||
content =
|
||||
parsedContent != null ? Map<String, dynamic>.from(parsedContent) : null;
|
||||
indexes = parsedIndexes != null
|
||||
? Map<String, int>.from(parsedIndexes)
|
||||
: <String, int>{};
|
||||
_setSenderKey(dbEntry.senderKey);
|
||||
_setSenderClaimedKeys(Map<String, String>.from(parsedSenderClaimedKeys));
|
||||
|
||||
inboundGroupSession = olm.InboundGroupSession();
|
||||
try {
|
||||
inboundGroupSession.unpickle(key, dbEntry.pickle);
|
||||
|
@ -57,6 +73,22 @@ class SessionKey {
|
|||
}
|
||||
}
|
||||
|
||||
void _setSenderKey(String key) {
|
||||
senderKey = key ?? content['sender_key'] ?? '';
|
||||
}
|
||||
|
||||
void _setSenderClaimedKeys(Map<String, String> keys) {
|
||||
senderClaimedKeys = (keys != null && keys.isNotEmpty)
|
||||
? keys
|
||||
: (content['sender_claimed_keys'] is Map
|
||||
? Map<String, String>.from(content['sender_claimed_keys'])
|
||||
: (content['sender_claimed_ed25519_key'] is String
|
||||
? <String, String>{
|
||||
'ed25519': content['sender_claimed_ed25519_key']
|
||||
}
|
||||
: <String, String>{}));
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final data = <String, dynamic>{};
|
||||
if (content != null) {
|
||||
|
|
|
@ -20,7 +20,7 @@ class Database extends _$Database {
|
|||
Database.connect(DatabaseConnection connection) : super.connect(connection);
|
||||
|
||||
@override
|
||||
int get schemaVersion => 5;
|
||||
int get schemaVersion => 6;
|
||||
|
||||
int get maxFileSize => 1 * 1024 * 1024;
|
||||
|
||||
|
@ -62,6 +62,15 @@ class Database extends _$Database {
|
|||
await m.addColumn(olmSessions, olmSessions.lastReceived);
|
||||
from++;
|
||||
}
|
||||
if (from == 5) {
|
||||
await m.addColumn(
|
||||
inboundGroupSessions, inboundGroupSessions.uploaded);
|
||||
await m.addColumn(
|
||||
inboundGroupSessions, inboundGroupSessions.senderKey);
|
||||
await m.addColumn(
|
||||
inboundGroupSessions, inboundGroupSessions.senderClaimedKeys);
|
||||
from++;
|
||||
}
|
||||
},
|
||||
beforeOpen: (_) async {
|
||||
if (executor.dialect == SqlDialect.sqlite) {
|
||||
|
|
|
@ -2062,19 +2062,26 @@ class DbInboundGroupSession extends DataClass
|
|||
final String pickle;
|
||||
final String content;
|
||||
final String indexes;
|
||||
final bool uploaded;
|
||||
final String senderKey;
|
||||
final String senderClaimedKeys;
|
||||
DbInboundGroupSession(
|
||||
{@required this.clientId,
|
||||
@required this.roomId,
|
||||
@required this.sessionId,
|
||||
@required this.pickle,
|
||||
this.content,
|
||||
this.indexes});
|
||||
this.indexes,
|
||||
this.uploaded,
|
||||
this.senderKey,
|
||||
this.senderClaimedKeys});
|
||||
factory DbInboundGroupSession.fromData(
|
||||
Map<String, dynamic> data, GeneratedDatabase db,
|
||||
{String prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
final intType = db.typeSystem.forDartType<int>();
|
||||
final stringType = db.typeSystem.forDartType<String>();
|
||||
final boolType = db.typeSystem.forDartType<bool>();
|
||||
return DbInboundGroupSession(
|
||||
clientId:
|
||||
intType.mapFromDatabaseResponse(data['${effectivePrefix}client_id']),
|
||||
|
@ -2088,6 +2095,12 @@ class DbInboundGroupSession extends DataClass
|
|||
stringType.mapFromDatabaseResponse(data['${effectivePrefix}content']),
|
||||
indexes:
|
||||
stringType.mapFromDatabaseResponse(data['${effectivePrefix}indexes']),
|
||||
uploaded:
|
||||
boolType.mapFromDatabaseResponse(data['${effectivePrefix}uploaded']),
|
||||
senderKey: stringType
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}sender_key']),
|
||||
senderClaimedKeys: stringType.mapFromDatabaseResponse(
|
||||
data['${effectivePrefix}sender_claimed_keys']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -2111,6 +2124,15 @@ class DbInboundGroupSession extends DataClass
|
|||
if (!nullToAbsent || indexes != null) {
|
||||
map['indexes'] = Variable<String>(indexes);
|
||||
}
|
||||
if (!nullToAbsent || uploaded != null) {
|
||||
map['uploaded'] = Variable<bool>(uploaded);
|
||||
}
|
||||
if (!nullToAbsent || senderKey != null) {
|
||||
map['sender_key'] = Variable<String>(senderKey);
|
||||
}
|
||||
if (!nullToAbsent || senderClaimedKeys != null) {
|
||||
map['sender_claimed_keys'] = Variable<String>(senderClaimedKeys);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -2124,6 +2146,10 @@ class DbInboundGroupSession extends DataClass
|
|||
pickle: serializer.fromJson<String>(json['pickle']),
|
||||
content: serializer.fromJson<String>(json['content']),
|
||||
indexes: serializer.fromJson<String>(json['indexes']),
|
||||
uploaded: serializer.fromJson<bool>(json['uploaded']),
|
||||
senderKey: serializer.fromJson<String>(json['sender_key']),
|
||||
senderClaimedKeys:
|
||||
serializer.fromJson<String>(json['sender_claimed_keys']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -2136,6 +2162,9 @@ class DbInboundGroupSession extends DataClass
|
|||
'pickle': serializer.toJson<String>(pickle),
|
||||
'content': serializer.toJson<String>(content),
|
||||
'indexes': serializer.toJson<String>(indexes),
|
||||
'uploaded': serializer.toJson<bool>(uploaded),
|
||||
'sender_key': serializer.toJson<String>(senderKey),
|
||||
'sender_claimed_keys': serializer.toJson<String>(senderClaimedKeys),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2145,7 +2174,10 @@ class DbInboundGroupSession extends DataClass
|
|||
String sessionId,
|
||||
String pickle,
|
||||
String content,
|
||||
String indexes}) =>
|
||||
String indexes,
|
||||
bool uploaded,
|
||||
String senderKey,
|
||||
String senderClaimedKeys}) =>
|
||||
DbInboundGroupSession(
|
||||
clientId: clientId ?? this.clientId,
|
||||
roomId: roomId ?? this.roomId,
|
||||
|
@ -2153,6 +2185,9 @@ class DbInboundGroupSession extends DataClass
|
|||
pickle: pickle ?? this.pickle,
|
||||
content: content ?? this.content,
|
||||
indexes: indexes ?? this.indexes,
|
||||
uploaded: uploaded ?? this.uploaded,
|
||||
senderKey: senderKey ?? this.senderKey,
|
||||
senderClaimedKeys: senderClaimedKeys ?? this.senderClaimedKeys,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
|
@ -2162,7 +2197,10 @@ class DbInboundGroupSession extends DataClass
|
|||
..write('sessionId: $sessionId, ')
|
||||
..write('pickle: $pickle, ')
|
||||
..write('content: $content, ')
|
||||
..write('indexes: $indexes')
|
||||
..write('indexes: $indexes, ')
|
||||
..write('uploaded: $uploaded, ')
|
||||
..write('senderKey: $senderKey, ')
|
||||
..write('senderClaimedKeys: $senderClaimedKeys')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
@ -2174,8 +2212,16 @@ class DbInboundGroupSession extends DataClass
|
|||
roomId.hashCode,
|
||||
$mrjc(
|
||||
sessionId.hashCode,
|
||||
$mrjc(pickle.hashCode,
|
||||
$mrjc(content.hashCode, indexes.hashCode))))));
|
||||
$mrjc(
|
||||
pickle.hashCode,
|
||||
$mrjc(
|
||||
content.hashCode,
|
||||
$mrjc(
|
||||
indexes.hashCode,
|
||||
$mrjc(
|
||||
uploaded.hashCode,
|
||||
$mrjc(senderKey.hashCode,
|
||||
senderClaimedKeys.hashCode)))))))));
|
||||
@override
|
||||
bool operator ==(dynamic other) =>
|
||||
identical(this, other) ||
|
||||
|
@ -2185,7 +2231,10 @@ class DbInboundGroupSession extends DataClass
|
|||
other.sessionId == this.sessionId &&
|
||||
other.pickle == this.pickle &&
|
||||
other.content == this.content &&
|
||||
other.indexes == this.indexes);
|
||||
other.indexes == this.indexes &&
|
||||
other.uploaded == this.uploaded &&
|
||||
other.senderKey == this.senderKey &&
|
||||
other.senderClaimedKeys == this.senderClaimedKeys);
|
||||
}
|
||||
|
||||
class InboundGroupSessionsCompanion
|
||||
|
@ -2196,6 +2245,9 @@ class InboundGroupSessionsCompanion
|
|||
final Value<String> pickle;
|
||||
final Value<String> content;
|
||||
final Value<String> indexes;
|
||||
final Value<bool> uploaded;
|
||||
final Value<String> senderKey;
|
||||
final Value<String> senderClaimedKeys;
|
||||
const InboundGroupSessionsCompanion({
|
||||
this.clientId = const Value.absent(),
|
||||
this.roomId = const Value.absent(),
|
||||
|
@ -2203,6 +2255,9 @@ class InboundGroupSessionsCompanion
|
|||
this.pickle = const Value.absent(),
|
||||
this.content = const Value.absent(),
|
||||
this.indexes = const Value.absent(),
|
||||
this.uploaded = const Value.absent(),
|
||||
this.senderKey = const Value.absent(),
|
||||
this.senderClaimedKeys = const Value.absent(),
|
||||
});
|
||||
InboundGroupSessionsCompanion.insert({
|
||||
@required int clientId,
|
||||
|
@ -2211,6 +2266,9 @@ class InboundGroupSessionsCompanion
|
|||
@required String pickle,
|
||||
this.content = const Value.absent(),
|
||||
this.indexes = const Value.absent(),
|
||||
this.uploaded = const Value.absent(),
|
||||
this.senderKey = const Value.absent(),
|
||||
this.senderClaimedKeys = const Value.absent(),
|
||||
}) : clientId = Value(clientId),
|
||||
roomId = Value(roomId),
|
||||
sessionId = Value(sessionId),
|
||||
|
@ -2222,6 +2280,9 @@ class InboundGroupSessionsCompanion
|
|||
Expression<String> pickle,
|
||||
Expression<String> content,
|
||||
Expression<String> indexes,
|
||||
Expression<bool> uploaded,
|
||||
Expression<String> senderKey,
|
||||
Expression<String> senderClaimedKeys,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (clientId != null) 'client_id': clientId,
|
||||
|
@ -2230,6 +2291,9 @@ class InboundGroupSessionsCompanion
|
|||
if (pickle != null) 'pickle': pickle,
|
||||
if (content != null) 'content': content,
|
||||
if (indexes != null) 'indexes': indexes,
|
||||
if (uploaded != null) 'uploaded': uploaded,
|
||||
if (senderKey != null) 'sender_key': senderKey,
|
||||
if (senderClaimedKeys != null) 'sender_claimed_keys': senderClaimedKeys,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2239,7 +2303,10 @@ class InboundGroupSessionsCompanion
|
|||
Value<String> sessionId,
|
||||
Value<String> pickle,
|
||||
Value<String> content,
|
||||
Value<String> indexes}) {
|
||||
Value<String> indexes,
|
||||
Value<bool> uploaded,
|
||||
Value<String> senderKey,
|
||||
Value<String> senderClaimedKeys}) {
|
||||
return InboundGroupSessionsCompanion(
|
||||
clientId: clientId ?? this.clientId,
|
||||
roomId: roomId ?? this.roomId,
|
||||
|
@ -2247,6 +2314,9 @@ class InboundGroupSessionsCompanion
|
|||
pickle: pickle ?? this.pickle,
|
||||
content: content ?? this.content,
|
||||
indexes: indexes ?? this.indexes,
|
||||
uploaded: uploaded ?? this.uploaded,
|
||||
senderKey: senderKey ?? this.senderKey,
|
||||
senderClaimedKeys: senderClaimedKeys ?? this.senderClaimedKeys,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2271,6 +2341,15 @@ class InboundGroupSessionsCompanion
|
|||
if (indexes.present) {
|
||||
map['indexes'] = Variable<String>(indexes.value);
|
||||
}
|
||||
if (uploaded.present) {
|
||||
map['uploaded'] = Variable<bool>(uploaded.value);
|
||||
}
|
||||
if (senderKey.present) {
|
||||
map['sender_key'] = Variable<String>(senderKey.value);
|
||||
}
|
||||
if (senderClaimedKeys.present) {
|
||||
map['sender_claimed_keys'] = Variable<String>(senderClaimedKeys.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
@ -2328,9 +2407,45 @@ class InboundGroupSessions extends Table
|
|||
$customConstraints: '');
|
||||
}
|
||||
|
||||
final VerificationMeta _uploadedMeta = const VerificationMeta('uploaded');
|
||||
GeneratedBoolColumn _uploaded;
|
||||
GeneratedBoolColumn get uploaded => _uploaded ??= _constructUploaded();
|
||||
GeneratedBoolColumn _constructUploaded() {
|
||||
return GeneratedBoolColumn('uploaded', $tableName, true,
|
||||
$customConstraints: 'DEFAULT false',
|
||||
defaultValue: const CustomExpression<bool>('false'));
|
||||
}
|
||||
|
||||
final VerificationMeta _senderKeyMeta = const VerificationMeta('senderKey');
|
||||
GeneratedTextColumn _senderKey;
|
||||
GeneratedTextColumn get senderKey => _senderKey ??= _constructSenderKey();
|
||||
GeneratedTextColumn _constructSenderKey() {
|
||||
return GeneratedTextColumn('sender_key', $tableName, true,
|
||||
$customConstraints: '');
|
||||
}
|
||||
|
||||
final VerificationMeta _senderClaimedKeysMeta =
|
||||
const VerificationMeta('senderClaimedKeys');
|
||||
GeneratedTextColumn _senderClaimedKeys;
|
||||
GeneratedTextColumn get senderClaimedKeys =>
|
||||
_senderClaimedKeys ??= _constructSenderClaimedKeys();
|
||||
GeneratedTextColumn _constructSenderClaimedKeys() {
|
||||
return GeneratedTextColumn('sender_claimed_keys', $tableName, true,
|
||||
$customConstraints: '');
|
||||
}
|
||||
|
||||
@override
|
||||
List<GeneratedColumn> get $columns =>
|
||||
[clientId, roomId, sessionId, pickle, content, indexes];
|
||||
List<GeneratedColumn> get $columns => [
|
||||
clientId,
|
||||
roomId,
|
||||
sessionId,
|
||||
pickle,
|
||||
content,
|
||||
indexes,
|
||||
uploaded,
|
||||
senderKey,
|
||||
senderClaimedKeys
|
||||
];
|
||||
@override
|
||||
InboundGroupSessions get asDslTable => this;
|
||||
@override
|
||||
|
@ -2375,6 +2490,20 @@ class InboundGroupSessions extends Table
|
|||
context.handle(_indexesMeta,
|
||||
indexes.isAcceptableOrUnknown(data['indexes'], _indexesMeta));
|
||||
}
|
||||
if (data.containsKey('uploaded')) {
|
||||
context.handle(_uploadedMeta,
|
||||
uploaded.isAcceptableOrUnknown(data['uploaded'], _uploadedMeta));
|
||||
}
|
||||
if (data.containsKey('sender_key')) {
|
||||
context.handle(_senderKeyMeta,
|
||||
senderKey.isAcceptableOrUnknown(data['sender_key'], _senderKeyMeta));
|
||||
}
|
||||
if (data.containsKey('sender_claimed_keys')) {
|
||||
context.handle(
|
||||
_senderClaimedKeysMeta,
|
||||
senderClaimedKeys.isAcceptableOrUnknown(
|
||||
data['sender_claimed_keys'], _senderClaimedKeysMeta));
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@ -5669,6 +5798,9 @@ abstract class _$Database extends GeneratedDatabase {
|
|||
pickle: row.readString('pickle'),
|
||||
content: row.readString('content'),
|
||||
indexes: row.readString('indexes'),
|
||||
uploaded: row.readBool('uploaded'),
|
||||
senderKey: row.readString('sender_key'),
|
||||
senderClaimedKeys: row.readString('sender_claimed_keys'),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -5701,17 +5833,26 @@ abstract class _$Database extends GeneratedDatabase {
|
|||
readsFrom: {inboundGroupSessions}).map(_rowToDbInboundGroupSession);
|
||||
}
|
||||
|
||||
Future<int> storeInboundGroupSession(int client_id, String room_id,
|
||||
String session_id, String pickle, String content, String indexes) {
|
||||
Future<int> storeInboundGroupSession(
|
||||
int client_id,
|
||||
String room_id,
|
||||
String session_id,
|
||||
String pickle,
|
||||
String content,
|
||||
String indexes,
|
||||
String sender_key,
|
||||
String sender_claimed_keys) {
|
||||
return customInsert(
|
||||
'INSERT OR REPLACE INTO inbound_group_sessions (client_id, room_id, session_id, pickle, content, indexes) VALUES (:client_id, :room_id, :session_id, :pickle, :content, :indexes)',
|
||||
'INSERT OR REPLACE INTO inbound_group_sessions (client_id, room_id, session_id, pickle, content, indexes, sender_key, sender_claimed_keys) VALUES (:client_id, :room_id, :session_id, :pickle, :content, :indexes, :sender_key, :sender_claimed_keys)',
|
||||
variables: [
|
||||
Variable.withInt(client_id),
|
||||
Variable.withString(room_id),
|
||||
Variable.withString(session_id),
|
||||
Variable.withString(pickle),
|
||||
Variable.withString(content),
|
||||
Variable.withString(indexes)
|
||||
Variable.withString(indexes),
|
||||
Variable.withString(sender_key),
|
||||
Variable.withString(sender_claimed_keys)
|
||||
],
|
||||
updates: {inboundGroupSessions},
|
||||
);
|
||||
|
|
|
@ -71,6 +71,9 @@ CREATE TABLE inbound_group_sessions (
|
|||
pickle TEXT NOT NULL,
|
||||
content TEXT,
|
||||
indexes TEXT,
|
||||
uploaded BOOLEAN DEFAULT false,
|
||||
sender_key TEXT,
|
||||
sender_claimed_keys TEXT,
|
||||
UNIQUE(client_id, room_id, session_id)
|
||||
) AS DbInboundGroupSession;
|
||||
CREATE INDEX inbound_group_sessions_index ON inbound_group_sessions(client_id);
|
||||
|
@ -186,7 +189,7 @@ removeOutboundGroupSession: DELETE FROM outbound_group_sessions WHERE client_id
|
|||
dbGetInboundGroupSessionKey: SELECT * FROM inbound_group_sessions WHERE client_id = :client_id AND room_id = :room_id AND session_id = :session_id;
|
||||
dbGetInboundGroupSessionKeys: SELECT * FROM inbound_group_sessions WHERE client_id = :client_id AND room_id = :room_id;
|
||||
getAllInboundGroupSessions: SELECT * FROM inbound_group_sessions WHERE client_id = :client_id;
|
||||
storeInboundGroupSession: INSERT OR REPLACE INTO inbound_group_sessions (client_id, room_id, session_id, pickle, content, indexes) VALUES (:client_id, :room_id, :session_id, :pickle, :content, :indexes);
|
||||
storeInboundGroupSession: INSERT OR REPLACE INTO inbound_group_sessions (client_id, room_id, session_id, pickle, content, indexes, sender_key, sender_claimed_keys) VALUES (:client_id, :room_id, :session_id, :pickle, :content, :indexes, :sender_key, :sender_claimed_keys);
|
||||
updateInboundGroupSessionIndexes: UPDATE inbound_group_sessions SET indexes = :indexes WHERE client_id = :client_id AND room_id = :room_id AND session_id = :session_id;
|
||||
storeUserDeviceKeysInfo: INSERT OR REPLACE INTO user_device_keys (client_id, user_id, outdated) VALUES (:client_id, :user_id, :outdated);
|
||||
setVerifiedUserDeviceKey: UPDATE user_device_keys_key SET verified = :verified WHERE client_id = :client_id AND user_id = :user_id AND device_id = :device_id;
|
||||
|
|
|
@ -60,7 +60,7 @@ void main() {
|
|||
'session_key': sessionKey,
|
||||
},
|
||||
encryptedContent: {
|
||||
'sender_key': validSessionId,
|
||||
'sender_key': validSenderKey,
|
||||
});
|
||||
await client.encryption.keyManager.handleToDeviceEvent(event);
|
||||
expect(
|
||||
|
@ -185,6 +185,11 @@ void main() {
|
|||
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||
null,
|
||||
true);
|
||||
expect(
|
||||
client.encryption.keyManager
|
||||
.getInboundGroupSession(roomId, sessionId, 'invalid') !=
|
||||
null,
|
||||
false);
|
||||
|
||||
expect(
|
||||
client.encryption.keyManager
|
||||
|
@ -196,6 +201,11 @@ void main() {
|
|||
.getInboundGroupSession('otherroom', sessionId, senderKey) !=
|
||||
null,
|
||||
true);
|
||||
expect(
|
||||
client.encryption.keyManager
|
||||
.getInboundGroupSession('otherroom', sessionId, 'invalid') !=
|
||||
null,
|
||||
false);
|
||||
expect(
|
||||
client.encryption.keyManager
|
||||
.getInboundGroupSession('otherroom', 'invalid', senderKey) !=
|
||||
|
@ -215,6 +225,20 @@ void main() {
|
|||
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||
null,
|
||||
true);
|
||||
|
||||
client.encryption.keyManager.clearInboundGroupSessions();
|
||||
expect(
|
||||
client.encryption.keyManager
|
||||
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||
null,
|
||||
false);
|
||||
await client.encryption.keyManager
|
||||
.loadInboundGroupSession(roomId, sessionId, 'invalid');
|
||||
expect(
|
||||
client.encryption.keyManager
|
||||
.getInboundGroupSession(roomId, sessionId, 'invalid') !=
|
||||
null,
|
||||
false);
|
||||
});
|
||||
|
||||
test('setInboundGroupSession', () async {
|
||||
|
|
|
@ -53,7 +53,7 @@ void main() {
|
|||
if (!olmEnabled) return;
|
||||
|
||||
final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
|
||||
final validSenderKey = '3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI';
|
||||
final validSenderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
|
||||
test('Create Request', () async {
|
||||
var matrix = await getClient();
|
||||
final requestRoom = matrix.getRoomById('!726s6s6q:example.com');
|
||||
|
|
Loading…
Reference in a new issue