pick the correct session when encrypting to_device events
This commit is contained in:
parent
f79a85ca71
commit
68fac1e112
|
@ -23,6 +23,7 @@ import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:famedlysdk/matrix_api.dart';
|
import 'package:famedlysdk/matrix_api.dart';
|
||||||
import 'package:olm/olm.dart' as olm;
|
import 'package:olm/olm.dart' as olm;
|
||||||
import './encryption.dart';
|
import './encryption.dart';
|
||||||
|
import './utils/olm_session.dart';
|
||||||
|
|
||||||
class OlmManager {
|
class OlmManager {
|
||||||
final Encryption encryption;
|
final Encryption encryption;
|
||||||
|
@ -43,8 +44,8 @@ class OlmManager {
|
||||||
OlmManager(this.encryption);
|
OlmManager(this.encryption);
|
||||||
|
|
||||||
/// A map from Curve25519 identity keys to existing olm sessions.
|
/// A map from Curve25519 identity keys to existing olm sessions.
|
||||||
Map<String, List<olm.Session>> get olmSessions => _olmSessions;
|
Map<String, List<OlmSession>> get olmSessions => _olmSessions;
|
||||||
final Map<String, List<olm.Session>> _olmSessions = {};
|
final Map<String, List<OlmSession>> _olmSessions = {};
|
||||||
|
|
||||||
Future<void> init(String olmAccount) async {
|
Future<void> init(String olmAccount) async {
|
||||||
if (olmAccount == null) {
|
if (olmAccount == null) {
|
||||||
|
@ -204,25 +205,24 @@ class OlmManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void storeOlmSession(String curve25519IdentityKey, olm.Session session) {
|
void storeOlmSession(OlmSession session) {
|
||||||
if (client.database == null) {
|
if (client.database == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!_olmSessions.containsKey(curve25519IdentityKey)) {
|
if (!_olmSessions.containsKey(session.identityKey)) {
|
||||||
_olmSessions[curve25519IdentityKey] = [];
|
_olmSessions[session.identityKey] = [];
|
||||||
}
|
}
|
||||||
final ix = _olmSessions[curve25519IdentityKey]
|
final ix = _olmSessions[session.identityKey]
|
||||||
.indexWhere((s) => s.session_id() == session.session_id());
|
.indexWhere((s) => s.sessionId == session.sessionId);
|
||||||
if (ix == -1) {
|
if (ix == -1) {
|
||||||
// add a new session
|
// add a new session
|
||||||
_olmSessions[curve25519IdentityKey].add(session);
|
_olmSessions[session.identityKey].add(session);
|
||||||
} else {
|
} else {
|
||||||
// update an existing session
|
// update an existing session
|
||||||
_olmSessions[curve25519IdentityKey][ix] = session;
|
_olmSessions[session.identityKey][ix] = session;
|
||||||
}
|
}
|
||||||
final pickle = session.pickle(client.userID);
|
client.database.storeOlmSession(client.id, session.identityKey,
|
||||||
client.database.storeOlmSession(
|
session.sessionId, session.pickledSession, session.lastReceived);
|
||||||
client.id, curve25519IdentityKey, session.session_id(), pickle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ToDeviceEvent _decryptToDeviceEvent(ToDeviceEvent event) {
|
ToDeviceEvent _decryptToDeviceEvent(ToDeviceEvent event) {
|
||||||
|
@ -245,14 +245,16 @@ class OlmManager {
|
||||||
var existingSessions = olmSessions[senderKey];
|
var existingSessions = olmSessions[senderKey];
|
||||||
if (existingSessions != null) {
|
if (existingSessions != null) {
|
||||||
for (var session in existingSessions) {
|
for (var session in existingSessions) {
|
||||||
if (type == 0 && session.matches_inbound(body) == true) {
|
if (type == 0 && session.session.matches_inbound(body) == true) {
|
||||||
plaintext = session.decrypt(type, body);
|
plaintext = session.session.decrypt(type, body);
|
||||||
storeOlmSession(senderKey, session);
|
session.lastReceived = DateTime.now();
|
||||||
|
storeOlmSession(session);
|
||||||
break;
|
break;
|
||||||
} else if (type == 1) {
|
} else if (type == 1) {
|
||||||
try {
|
try {
|
||||||
plaintext = session.decrypt(type, body);
|
plaintext = session.session.decrypt(type, body);
|
||||||
storeOlmSession(senderKey, session);
|
session.lastReceived = DateTime.now();
|
||||||
|
storeOlmSession(session);
|
||||||
break;
|
break;
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
plaintext = null;
|
plaintext = null;
|
||||||
|
@ -271,7 +273,13 @@ class OlmManager {
|
||||||
_olmAccount.remove_one_time_keys(newSession);
|
_olmAccount.remove_one_time_keys(newSession);
|
||||||
client.database?.updateClientKeys(pickledOlmAccount, client.id);
|
client.database?.updateClientKeys(pickledOlmAccount, client.id);
|
||||||
plaintext = newSession.decrypt(type, body);
|
plaintext = newSession.decrypt(type, body);
|
||||||
storeOlmSession(senderKey, newSession);
|
storeOlmSession(OlmSession(
|
||||||
|
key: client.userID,
|
||||||
|
identityKey: identityKey,
|
||||||
|
sessionId: newSession.session_id(),
|
||||||
|
session: newSession,
|
||||||
|
lastReceived: DateTime.now(),
|
||||||
|
));
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
newSession?.free();
|
newSession?.free();
|
||||||
rethrow;
|
rethrow;
|
||||||
|
@ -299,6 +307,22 @@ class OlmManager {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<OlmSession>> getOlmSessionsFromDatabase(String senderKey) async {
|
||||||
|
if (client.database == null) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
final rows =
|
||||||
|
await client.database.dbGetOlmSessions(client.id, senderKey).get();
|
||||||
|
final res = <OlmSession>[];
|
||||||
|
for (final row in rows) {
|
||||||
|
final sess = OlmSession.fromDb(row, client.userID);
|
||||||
|
if (sess.isValid) {
|
||||||
|
res.add(sess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
Future<ToDeviceEvent> decryptToDeviceEvent(ToDeviceEvent event) async {
|
Future<ToDeviceEvent> decryptToDeviceEvent(ToDeviceEvent event) async {
|
||||||
if (event.type != EventTypes.Encrypted) {
|
if (event.type != EventTypes.Encrypted) {
|
||||||
return event;
|
return event;
|
||||||
|
@ -308,8 +332,7 @@ class OlmManager {
|
||||||
if (client.database == null) {
|
if (client.database == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final sessions = await client.database
|
final sessions = await getOlmSessionsFromDatabase(senderKey);
|
||||||
.getSingleOlmSessions(client.id, senderKey, client.userID);
|
|
||||||
if (sessions.isEmpty) {
|
if (sessions.isEmpty) {
|
||||||
return false; // okay, can't do anything
|
return false; // okay, can't do anything
|
||||||
}
|
}
|
||||||
|
@ -352,11 +375,18 @@ class OlmManager {
|
||||||
fingerprintKey, deviceKey, userId, deviceId)) {
|
fingerprintKey, deviceKey, userId, deviceId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
var session = olm.Session();
|
||||||
try {
|
try {
|
||||||
var session = olm.Session();
|
|
||||||
session.create_outbound(_olmAccount, identityKey, deviceKey['key']);
|
session.create_outbound(_olmAccount, identityKey, deviceKey['key']);
|
||||||
await storeOlmSession(identityKey, session);
|
await storeOlmSession(OlmSession(
|
||||||
|
key: client.userID,
|
||||||
|
identityKey: identityKey,
|
||||||
|
sessionId: session.session_id(),
|
||||||
|
session: session,
|
||||||
|
lastReceived: null,
|
||||||
|
));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
session.free();
|
||||||
print('[LibOlm] Could not create new outbound olm session: ' +
|
print('[LibOlm] Could not create new outbound olm session: ' +
|
||||||
e.toString());
|
e.toString());
|
||||||
}
|
}
|
||||||
|
@ -369,14 +399,15 @@ class OlmManager {
|
||||||
DeviceKeys device, String type, Map<String, dynamic> payload) async {
|
DeviceKeys device, String type, Map<String, dynamic> payload) async {
|
||||||
var sess = olmSessions[device.curve25519Key];
|
var sess = olmSessions[device.curve25519Key];
|
||||||
if (sess == null || sess.isEmpty) {
|
if (sess == null || sess.isEmpty) {
|
||||||
final sessions = await client.database
|
final sessions = await getOlmSessionsFromDatabase(device.curve25519Key);
|
||||||
.getSingleOlmSessions(client.id, device.curve25519Key, client.userID);
|
|
||||||
if (sessions.isEmpty) {
|
if (sessions.isEmpty) {
|
||||||
throw ('No olm session found');
|
throw ('No olm session found');
|
||||||
}
|
}
|
||||||
sess = _olmSessions[device.curve25519Key] = sessions;
|
sess = _olmSessions[device.curve25519Key] = sessions;
|
||||||
}
|
}
|
||||||
sess.sort((a, b) => a.session_id().compareTo(b.session_id()));
|
sess.sort((a, b) => a.lastReceived == b.lastReceived
|
||||||
|
? a.sessionId.compareTo(b.sessionId)
|
||||||
|
: b.lastReceived.compareTo(a.lastReceived));
|
||||||
final fullPayload = {
|
final fullPayload = {
|
||||||
'type': type,
|
'type': type,
|
||||||
'content': payload,
|
'content': payload,
|
||||||
|
@ -385,8 +416,8 @@ class OlmManager {
|
||||||
'recipient': device.userId,
|
'recipient': device.userId,
|
||||||
'recipient_keys': {'ed25519': device.ed25519Key},
|
'recipient_keys': {'ed25519': device.ed25519Key},
|
||||||
};
|
};
|
||||||
final encryptResult = sess.first.encrypt(json.encode(fullPayload));
|
final encryptResult = sess.first.session.encrypt(json.encode(fullPayload));
|
||||||
storeOlmSession(device.curve25519Key, sess.first);
|
storeOlmSession(sess.first);
|
||||||
final encryptedBody = <String, dynamic>{
|
final encryptedBody = <String, dynamic>{
|
||||||
'algorithm': 'm.olm.v1.curve25519-aes-sha2',
|
'algorithm': 'm.olm.v1.curve25519-aes-sha2',
|
||||||
'sender_key': identityKey,
|
'sender_key': identityKey,
|
||||||
|
@ -440,7 +471,7 @@ class OlmManager {
|
||||||
void dispose() {
|
void dispose() {
|
||||||
for (final sessions in olmSessions.values) {
|
for (final sessions in olmSessions.values) {
|
||||||
for (final sess in sessions) {
|
for (final sess in sessions) {
|
||||||
sess.free();
|
sess.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_olmAccount?.free();
|
_olmAccount?.free();
|
||||||
|
|
59
lib/encryption/utils/olm_session.dart
Normal file
59
lib/encryption/utils/olm_session.dart
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Famedly Matrix SDK
|
||||||
|
* Copyright (C) 2020 Famedly GmbH
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'package:olm/olm.dart' as olm;
|
||||||
|
import '../../src/database/database.dart' show DbOlmSessions;
|
||||||
|
|
||||||
|
class OlmSession {
|
||||||
|
String identityKey;
|
||||||
|
String sessionId;
|
||||||
|
olm.Session session;
|
||||||
|
DateTime lastReceived;
|
||||||
|
final String key;
|
||||||
|
String get pickledSession => session.pickle(key);
|
||||||
|
|
||||||
|
bool get isValid => session != null;
|
||||||
|
|
||||||
|
OlmSession({
|
||||||
|
this.key,
|
||||||
|
this.identityKey,
|
||||||
|
this.sessionId,
|
||||||
|
this.session,
|
||||||
|
this.lastReceived,
|
||||||
|
});
|
||||||
|
|
||||||
|
OlmSession.fromDb(DbOlmSessions dbEntry, String key) : key = key {
|
||||||
|
session = olm.Session();
|
||||||
|
try {
|
||||||
|
session.unpickle(key, dbEntry.pickle);
|
||||||
|
identityKey = dbEntry.identityKey;
|
||||||
|
sessionId = dbEntry.identityKey;
|
||||||
|
lastReceived =
|
||||||
|
dbEntry.lastReceived ?? DateTime.fromMillisecondsSinceEpoch(0);
|
||||||
|
assert(sessionId == session.session_id());
|
||||||
|
} catch (e) {
|
||||||
|
print('[LibOlm] Could not unpickle olm session: ' + e.toString());
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
session?.free();
|
||||||
|
session = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ class Database extends _$Database {
|
||||||
Database(QueryExecutor e) : super(e);
|
Database(QueryExecutor e) : super(e);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 4;
|
int get schemaVersion => 5;
|
||||||
|
|
||||||
int get maxFileSize => 1 * 1024 * 1024;
|
int get maxFileSize => 1 * 1024 * 1024;
|
||||||
|
|
||||||
|
@ -55,6 +55,10 @@ class Database extends _$Database {
|
||||||
'UPDATE user_device_keys SET outdated = true');
|
'UPDATE user_device_keys SET outdated = true');
|
||||||
from++;
|
from++;
|
||||||
}
|
}
|
||||||
|
if (from == 4) {
|
||||||
|
await m.addColumn(olmSessions, olmSessions.lastReceived);
|
||||||
|
from++;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
beforeOpen: (_) async {
|
beforeOpen: (_) async {
|
||||||
if (executor.dialect == SqlDialect.sqlite) {
|
if (executor.dialect == SqlDialect.sqlite) {
|
||||||
|
@ -114,22 +118,6 @@ class Database extends _$Database {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<olm.Session>> getSingleOlmSessions(
|
|
||||||
int clientId, String identityKey, String userId) async {
|
|
||||||
final rows = await dbGetOlmSessions(clientId, identityKey).get();
|
|
||||||
final res = <olm.Session>[];
|
|
||||||
for (final row in rows) {
|
|
||||||
try {
|
|
||||||
var session = olm.Session();
|
|
||||||
session.unpickle(userId, row.pickle);
|
|
||||||
res.add(session);
|
|
||||||
} catch (e) {
|
|
||||||
print('[LibOlm] Could not unpickle olm session: ' + e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<DbOutboundGroupSession> getDbOutboundGroupSession(
|
Future<DbOutboundGroupSession> getDbOutboundGroupSession(
|
||||||
int clientId, String roomId) async {
|
int clientId, String roomId) async {
|
||||||
final res = await dbGetOutboundGroupSession(clientId, roomId).get();
|
final res = await dbGetOutboundGroupSession(clientId, roomId).get();
|
||||||
|
|
|
@ -1391,17 +1391,20 @@ class DbOlmSessions extends DataClass implements Insertable<DbOlmSessions> {
|
||||||
final String identityKey;
|
final String identityKey;
|
||||||
final String sessionId;
|
final String sessionId;
|
||||||
final String pickle;
|
final String pickle;
|
||||||
|
final DateTime lastReceived;
|
||||||
DbOlmSessions(
|
DbOlmSessions(
|
||||||
{@required this.clientId,
|
{@required this.clientId,
|
||||||
@required this.identityKey,
|
@required this.identityKey,
|
||||||
@required this.sessionId,
|
@required this.sessionId,
|
||||||
@required this.pickle});
|
@required this.pickle,
|
||||||
|
this.lastReceived});
|
||||||
factory DbOlmSessions.fromData(
|
factory DbOlmSessions.fromData(
|
||||||
Map<String, dynamic> data, GeneratedDatabase db,
|
Map<String, dynamic> data, GeneratedDatabase db,
|
||||||
{String prefix}) {
|
{String prefix}) {
|
||||||
final effectivePrefix = prefix ?? '';
|
final effectivePrefix = prefix ?? '';
|
||||||
final intType = db.typeSystem.forDartType<int>();
|
final intType = db.typeSystem.forDartType<int>();
|
||||||
final stringType = db.typeSystem.forDartType<String>();
|
final stringType = db.typeSystem.forDartType<String>();
|
||||||
|
final dateTimeType = db.typeSystem.forDartType<DateTime>();
|
||||||
return DbOlmSessions(
|
return DbOlmSessions(
|
||||||
clientId:
|
clientId:
|
||||||
intType.mapFromDatabaseResponse(data['${effectivePrefix}client_id']),
|
intType.mapFromDatabaseResponse(data['${effectivePrefix}client_id']),
|
||||||
|
@ -1411,6 +1414,8 @@ class DbOlmSessions extends DataClass implements Insertable<DbOlmSessions> {
|
||||||
.mapFromDatabaseResponse(data['${effectivePrefix}session_id']),
|
.mapFromDatabaseResponse(data['${effectivePrefix}session_id']),
|
||||||
pickle:
|
pickle:
|
||||||
stringType.mapFromDatabaseResponse(data['${effectivePrefix}pickle']),
|
stringType.mapFromDatabaseResponse(data['${effectivePrefix}pickle']),
|
||||||
|
lastReceived: dateTimeType
|
||||||
|
.mapFromDatabaseResponse(data['${effectivePrefix}last_received']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
|
@ -1428,6 +1433,9 @@ class DbOlmSessions extends DataClass implements Insertable<DbOlmSessions> {
|
||||||
if (!nullToAbsent || pickle != null) {
|
if (!nullToAbsent || pickle != null) {
|
||||||
map['pickle'] = Variable<String>(pickle);
|
map['pickle'] = Variable<String>(pickle);
|
||||||
}
|
}
|
||||||
|
if (!nullToAbsent || lastReceived != null) {
|
||||||
|
map['last_received'] = Variable<DateTime>(lastReceived);
|
||||||
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1439,6 +1447,7 @@ class DbOlmSessions extends DataClass implements Insertable<DbOlmSessions> {
|
||||||
identityKey: serializer.fromJson<String>(json['identity_key']),
|
identityKey: serializer.fromJson<String>(json['identity_key']),
|
||||||
sessionId: serializer.fromJson<String>(json['session_id']),
|
sessionId: serializer.fromJson<String>(json['session_id']),
|
||||||
pickle: serializer.fromJson<String>(json['pickle']),
|
pickle: serializer.fromJson<String>(json['pickle']),
|
||||||
|
lastReceived: serializer.fromJson<DateTime>(json['last_received']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
|
@ -1449,6 +1458,7 @@ class DbOlmSessions extends DataClass implements Insertable<DbOlmSessions> {
|
||||||
'identity_key': serializer.toJson<String>(identityKey),
|
'identity_key': serializer.toJson<String>(identityKey),
|
||||||
'session_id': serializer.toJson<String>(sessionId),
|
'session_id': serializer.toJson<String>(sessionId),
|
||||||
'pickle': serializer.toJson<String>(pickle),
|
'pickle': serializer.toJson<String>(pickle),
|
||||||
|
'last_received': serializer.toJson<DateTime>(lastReceived),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1456,12 +1466,14 @@ class DbOlmSessions extends DataClass implements Insertable<DbOlmSessions> {
|
||||||
{int clientId,
|
{int clientId,
|
||||||
String identityKey,
|
String identityKey,
|
||||||
String sessionId,
|
String sessionId,
|
||||||
String pickle}) =>
|
String pickle,
|
||||||
|
DateTime lastReceived}) =>
|
||||||
DbOlmSessions(
|
DbOlmSessions(
|
||||||
clientId: clientId ?? this.clientId,
|
clientId: clientId ?? this.clientId,
|
||||||
identityKey: identityKey ?? this.identityKey,
|
identityKey: identityKey ?? this.identityKey,
|
||||||
sessionId: sessionId ?? this.sessionId,
|
sessionId: sessionId ?? this.sessionId,
|
||||||
pickle: pickle ?? this.pickle,
|
pickle: pickle ?? this.pickle,
|
||||||
|
lastReceived: lastReceived ?? this.lastReceived,
|
||||||
);
|
);
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
|
@ -1469,14 +1481,19 @@ class DbOlmSessions extends DataClass implements Insertable<DbOlmSessions> {
|
||||||
..write('clientId: $clientId, ')
|
..write('clientId: $clientId, ')
|
||||||
..write('identityKey: $identityKey, ')
|
..write('identityKey: $identityKey, ')
|
||||||
..write('sessionId: $sessionId, ')
|
..write('sessionId: $sessionId, ')
|
||||||
..write('pickle: $pickle')
|
..write('pickle: $pickle, ')
|
||||||
|
..write('lastReceived: $lastReceived')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => $mrjf($mrjc(clientId.hashCode,
|
int get hashCode => $mrjf($mrjc(
|
||||||
$mrjc(identityKey.hashCode, $mrjc(sessionId.hashCode, pickle.hashCode))));
|
clientId.hashCode,
|
||||||
|
$mrjc(
|
||||||
|
identityKey.hashCode,
|
||||||
|
$mrjc(sessionId.hashCode,
|
||||||
|
$mrjc(pickle.hashCode, lastReceived.hashCode)))));
|
||||||
@override
|
@override
|
||||||
bool operator ==(dynamic other) =>
|
bool operator ==(dynamic other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
|
@ -1484,7 +1501,8 @@ class DbOlmSessions extends DataClass implements Insertable<DbOlmSessions> {
|
||||||
other.clientId == this.clientId &&
|
other.clientId == this.clientId &&
|
||||||
other.identityKey == this.identityKey &&
|
other.identityKey == this.identityKey &&
|
||||||
other.sessionId == this.sessionId &&
|
other.sessionId == this.sessionId &&
|
||||||
other.pickle == this.pickle);
|
other.pickle == this.pickle &&
|
||||||
|
other.lastReceived == this.lastReceived);
|
||||||
}
|
}
|
||||||
|
|
||||||
class OlmSessionsCompanion extends UpdateCompanion<DbOlmSessions> {
|
class OlmSessionsCompanion extends UpdateCompanion<DbOlmSessions> {
|
||||||
|
@ -1492,17 +1510,20 @@ class OlmSessionsCompanion extends UpdateCompanion<DbOlmSessions> {
|
||||||
final Value<String> identityKey;
|
final Value<String> identityKey;
|
||||||
final Value<String> sessionId;
|
final Value<String> sessionId;
|
||||||
final Value<String> pickle;
|
final Value<String> pickle;
|
||||||
|
final Value<DateTime> lastReceived;
|
||||||
const OlmSessionsCompanion({
|
const OlmSessionsCompanion({
|
||||||
this.clientId = const Value.absent(),
|
this.clientId = const Value.absent(),
|
||||||
this.identityKey = const Value.absent(),
|
this.identityKey = const Value.absent(),
|
||||||
this.sessionId = const Value.absent(),
|
this.sessionId = const Value.absent(),
|
||||||
this.pickle = const Value.absent(),
|
this.pickle = const Value.absent(),
|
||||||
|
this.lastReceived = const Value.absent(),
|
||||||
});
|
});
|
||||||
OlmSessionsCompanion.insert({
|
OlmSessionsCompanion.insert({
|
||||||
@required int clientId,
|
@required int clientId,
|
||||||
@required String identityKey,
|
@required String identityKey,
|
||||||
@required String sessionId,
|
@required String sessionId,
|
||||||
@required String pickle,
|
@required String pickle,
|
||||||
|
this.lastReceived = const Value.absent(),
|
||||||
}) : clientId = Value(clientId),
|
}) : clientId = Value(clientId),
|
||||||
identityKey = Value(identityKey),
|
identityKey = Value(identityKey),
|
||||||
sessionId = Value(sessionId),
|
sessionId = Value(sessionId),
|
||||||
|
@ -1512,12 +1533,14 @@ class OlmSessionsCompanion extends UpdateCompanion<DbOlmSessions> {
|
||||||
Expression<String> identityKey,
|
Expression<String> identityKey,
|
||||||
Expression<String> sessionId,
|
Expression<String> sessionId,
|
||||||
Expression<String> pickle,
|
Expression<String> pickle,
|
||||||
|
Expression<DateTime> lastReceived,
|
||||||
}) {
|
}) {
|
||||||
return RawValuesInsertable({
|
return RawValuesInsertable({
|
||||||
if (clientId != null) 'client_id': clientId,
|
if (clientId != null) 'client_id': clientId,
|
||||||
if (identityKey != null) 'identity_key': identityKey,
|
if (identityKey != null) 'identity_key': identityKey,
|
||||||
if (sessionId != null) 'session_id': sessionId,
|
if (sessionId != null) 'session_id': sessionId,
|
||||||
if (pickle != null) 'pickle': pickle,
|
if (pickle != null) 'pickle': pickle,
|
||||||
|
if (lastReceived != null) 'last_received': lastReceived,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1525,12 +1548,14 @@ class OlmSessionsCompanion extends UpdateCompanion<DbOlmSessions> {
|
||||||
{Value<int> clientId,
|
{Value<int> clientId,
|
||||||
Value<String> identityKey,
|
Value<String> identityKey,
|
||||||
Value<String> sessionId,
|
Value<String> sessionId,
|
||||||
Value<String> pickle}) {
|
Value<String> pickle,
|
||||||
|
Value<DateTime> lastReceived}) {
|
||||||
return OlmSessionsCompanion(
|
return OlmSessionsCompanion(
|
||||||
clientId: clientId ?? this.clientId,
|
clientId: clientId ?? this.clientId,
|
||||||
identityKey: identityKey ?? this.identityKey,
|
identityKey: identityKey ?? this.identityKey,
|
||||||
sessionId: sessionId ?? this.sessionId,
|
sessionId: sessionId ?? this.sessionId,
|
||||||
pickle: pickle ?? this.pickle,
|
pickle: pickle ?? this.pickle,
|
||||||
|
lastReceived: lastReceived ?? this.lastReceived,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1549,6 +1574,9 @@ class OlmSessionsCompanion extends UpdateCompanion<DbOlmSessions> {
|
||||||
if (pickle.present) {
|
if (pickle.present) {
|
||||||
map['pickle'] = Variable<String>(pickle.value);
|
map['pickle'] = Variable<String>(pickle.value);
|
||||||
}
|
}
|
||||||
|
if (lastReceived.present) {
|
||||||
|
map['last_received'] = Variable<DateTime>(lastReceived.value);
|
||||||
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1591,9 +1619,19 @@ class OlmSessions extends Table with TableInfo<OlmSessions, DbOlmSessions> {
|
||||||
$customConstraints: 'NOT NULL');
|
$customConstraints: 'NOT NULL');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final VerificationMeta _lastReceivedMeta =
|
||||||
|
const VerificationMeta('lastReceived');
|
||||||
|
GeneratedDateTimeColumn _lastReceived;
|
||||||
|
GeneratedDateTimeColumn get lastReceived =>
|
||||||
|
_lastReceived ??= _constructLastReceived();
|
||||||
|
GeneratedDateTimeColumn _constructLastReceived() {
|
||||||
|
return GeneratedDateTimeColumn('last_received', $tableName, true,
|
||||||
|
$customConstraints: '');
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<GeneratedColumn> get $columns =>
|
List<GeneratedColumn> get $columns =>
|
||||||
[clientId, identityKey, sessionId, pickle];
|
[clientId, identityKey, sessionId, pickle, lastReceived];
|
||||||
@override
|
@override
|
||||||
OlmSessions get asDslTable => this;
|
OlmSessions get asDslTable => this;
|
||||||
@override
|
@override
|
||||||
|
@ -1631,6 +1669,12 @@ class OlmSessions extends Table with TableInfo<OlmSessions, DbOlmSessions> {
|
||||||
} else if (isInserting) {
|
} else if (isInserting) {
|
||||||
context.missing(_pickleMeta);
|
context.missing(_pickleMeta);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('last_received')) {
|
||||||
|
context.handle(
|
||||||
|
_lastReceivedMeta,
|
||||||
|
lastReceived.isAcceptableOrUnknown(
|
||||||
|
data['last_received'], _lastReceivedMeta));
|
||||||
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5520,6 +5564,7 @@ abstract class _$Database extends GeneratedDatabase {
|
||||||
identityKey: row.readString('identity_key'),
|
identityKey: row.readString('identity_key'),
|
||||||
sessionId: row.readString('session_id'),
|
sessionId: row.readString('session_id'),
|
||||||
pickle: row.readString('pickle'),
|
pickle: row.readString('pickle'),
|
||||||
|
lastReceived: row.readDateTime('last_received'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5543,15 +5588,16 @@ abstract class _$Database extends GeneratedDatabase {
|
||||||
}).map(_rowToDbOlmSessions);
|
}).map(_rowToDbOlmSessions);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> storeOlmSession(
|
Future<int> storeOlmSession(int client_id, String identitiy_key,
|
||||||
int client_id, String identitiy_key, String session_id, String pickle) {
|
String session_id, String pickle, DateTime last_received) {
|
||||||
return customInsert(
|
return customInsert(
|
||||||
'INSERT OR REPLACE INTO olm_sessions (client_id, identity_key, session_id, pickle) VALUES (:client_id, :identitiy_key, :session_id, :pickle)',
|
'INSERT OR REPLACE INTO olm_sessions (client_id, identity_key, session_id, pickle, last_received) VALUES (:client_id, :identitiy_key, :session_id, :pickle, :last_received)',
|
||||||
variables: [
|
variables: [
|
||||||
Variable.withInt(client_id),
|
Variable.withInt(client_id),
|
||||||
Variable.withString(identitiy_key),
|
Variable.withString(identitiy_key),
|
||||||
Variable.withString(session_id),
|
Variable.withString(session_id),
|
||||||
Variable.withString(pickle)
|
Variable.withString(pickle),
|
||||||
|
Variable.withDateTime(last_received)
|
||||||
],
|
],
|
||||||
updates: {olmSessions},
|
updates: {olmSessions},
|
||||||
);
|
);
|
||||||
|
|
|
@ -48,6 +48,7 @@ CREATE TABLE olm_sessions (
|
||||||
identity_key TEXT NOT NULL,
|
identity_key TEXT NOT NULL,
|
||||||
session_id TEXT NOT NULL,
|
session_id TEXT NOT NULL,
|
||||||
pickle TEXT NOT NULL,
|
pickle TEXT NOT NULL,
|
||||||
|
last_received DATETIME,
|
||||||
UNIQUE(client_id, identity_key, session_id)
|
UNIQUE(client_id, identity_key, session_id)
|
||||||
) AS DbOlmSessions;
|
) AS DbOlmSessions;
|
||||||
CREATE INDEX olm_sessions_index ON olm_sessions(client_id);
|
CREATE INDEX olm_sessions_index ON olm_sessions(client_id);
|
||||||
|
@ -177,7 +178,7 @@ getAllUserDeviceKeysKeys: SELECT * FROM user_device_keys_key WHERE client_id = :
|
||||||
getAllUserCrossSigningKeys: SELECT * FROM user_cross_signing_keys WHERE client_id = :client_id;
|
getAllUserCrossSigningKeys: SELECT * FROM user_cross_signing_keys WHERE client_id = :client_id;
|
||||||
getAllOlmSessions: SELECT * FROM olm_sessions WHERE client_id = :client_id;
|
getAllOlmSessions: SELECT * FROM olm_sessions WHERE client_id = :client_id;
|
||||||
dbGetOlmSessions: SELECT * FROM olm_sessions WHERE client_id = :client_id AND identity_key = :identity_key;
|
dbGetOlmSessions: SELECT * FROM olm_sessions WHERE client_id = :client_id AND identity_key = :identity_key;
|
||||||
storeOlmSession: INSERT OR REPLACE INTO olm_sessions (client_id, identity_key, session_id, pickle) VALUES (:client_id, :identitiy_key, :session_id, :pickle);
|
storeOlmSession: INSERT OR REPLACE INTO olm_sessions (client_id, identity_key, session_id, pickle, last_received) VALUES (:client_id, :identitiy_key, :session_id, :pickle, :last_received);
|
||||||
getAllOutboundGroupSessions: SELECT * FROM outbound_group_sessions WHERE client_id = :client_id;
|
getAllOutboundGroupSessions: SELECT * FROM outbound_group_sessions WHERE client_id = :client_id;
|
||||||
dbGetOutboundGroupSession: SELECT * FROM outbound_group_sessions WHERE client_id = :client_id AND room_id = :room_id;
|
dbGetOutboundGroupSession: SELECT * FROM outbound_group_sessions WHERE client_id = :client_id AND room_id = :room_id;
|
||||||
storeOutboundGroupSession: INSERT OR REPLACE INTO outbound_group_sessions (client_id, room_id, pickle, device_ids, creation_time, sent_messages) VALUES (:client_id, :room_id, :pickle, :device_ids, :creation_time, :sent_messages);
|
storeOutboundGroupSession: INSERT OR REPLACE INTO outbound_group_sessions (client_id, room_id, pickle, device_ids, creation_time, sent_messages) VALUES (:client_id, :room_id, :pickle, :device_ids, :creation_time, :sent_messages);
|
||||||
|
|
|
@ -139,12 +139,10 @@ void test() async {
|
||||||
assert(testClientB
|
assert(testClientB
|
||||||
.encryption.olmManager.olmSessions[testClientA.identityKey].length ==
|
.encryption.olmManager.olmSessions[testClientA.identityKey].length ==
|
||||||
1);
|
1);
|
||||||
assert(testClientA
|
assert(testClientA.encryption.olmManager.olmSessions[testClientB.identityKey]
|
||||||
.encryption.olmManager.olmSessions[testClientB.identityKey].first
|
.first.sessionId ==
|
||||||
.session_id() ==
|
testClientB.encryption.olmManager.olmSessions[testClientA.identityKey]
|
||||||
testClientB
|
.first.sessionId);
|
||||||
.encryption.olmManager.olmSessions[testClientA.identityKey].first
|
|
||||||
.session_id());
|
|
||||||
assert(inviteRoom.client.encryption.keyManager
|
assert(inviteRoom.client.encryption.keyManager
|
||||||
.getInboundGroupSession(inviteRoom.id, currentSessionIdA, '') !=
|
.getInboundGroupSession(inviteRoom.id, currentSessionIdA, '') !=
|
||||||
null);
|
null);
|
||||||
|
@ -162,12 +160,10 @@ void test() async {
|
||||||
assert(testClientB
|
assert(testClientB
|
||||||
.encryption.olmManager.olmSessions[testClientA.identityKey].length ==
|
.encryption.olmManager.olmSessions[testClientA.identityKey].length ==
|
||||||
1);
|
1);
|
||||||
assert(testClientA
|
assert(testClientA.encryption.olmManager.olmSessions[testClientB.identityKey]
|
||||||
.encryption.olmManager.olmSessions[testClientB.identityKey].first
|
.first.sessionId ==
|
||||||
.session_id() ==
|
testClientB.encryption.olmManager.olmSessions[testClientA.identityKey]
|
||||||
testClientB
|
.first.sessionId);
|
||||||
.encryption.olmManager.olmSessions[testClientA.identityKey].first
|
|
||||||
.session_id());
|
|
||||||
|
|
||||||
assert(room.client.encryption.keyManager
|
assert(room.client.encryption.keyManager
|
||||||
.getOutboundGroupSession(room.id)
|
.getOutboundGroupSession(room.id)
|
||||||
|
@ -231,24 +227,20 @@ void test() async {
|
||||||
assert(testClientB
|
assert(testClientB
|
||||||
.encryption.olmManager.olmSessions[testClientA.identityKey].length ==
|
.encryption.olmManager.olmSessions[testClientA.identityKey].length ==
|
||||||
1);
|
1);
|
||||||
assert(testClientA
|
assert(testClientA.encryption.olmManager.olmSessions[testClientB.identityKey]
|
||||||
.encryption.olmManager.olmSessions[testClientB.identityKey].first
|
.first.sessionId ==
|
||||||
.session_id() ==
|
testClientB.encryption.olmManager.olmSessions[testClientA.identityKey]
|
||||||
testClientB
|
.first.sessionId);
|
||||||
.encryption.olmManager.olmSessions[testClientA.identityKey].first
|
|
||||||
.session_id());
|
|
||||||
assert(testClientA
|
assert(testClientA
|
||||||
.encryption.olmManager.olmSessions[testClientC.identityKey].length ==
|
.encryption.olmManager.olmSessions[testClientC.identityKey].length ==
|
||||||
1);
|
1);
|
||||||
assert(testClientC
|
assert(testClientC
|
||||||
.encryption.olmManager.olmSessions[testClientA.identityKey].length ==
|
.encryption.olmManager.olmSessions[testClientA.identityKey].length ==
|
||||||
1);
|
1);
|
||||||
assert(testClientA
|
assert(testClientA.encryption.olmManager.olmSessions[testClientC.identityKey]
|
||||||
.encryption.olmManager.olmSessions[testClientC.identityKey].first
|
.first.sessionId ==
|
||||||
.session_id() ==
|
testClientC.encryption.olmManager.olmSessions[testClientA.identityKey]
|
||||||
testClientC
|
.first.sessionId);
|
||||||
.encryption.olmManager.olmSessions[testClientA.identityKey].first
|
|
||||||
.session_id());
|
|
||||||
assert(room.client.encryption.keyManager
|
assert(room.client.encryption.keyManager
|
||||||
.getOutboundGroupSession(room.id)
|
.getOutboundGroupSession(room.id)
|
||||||
.outboundGroupSession
|
.outboundGroupSession
|
||||||
|
@ -281,12 +273,10 @@ void test() async {
|
||||||
assert(testClientB
|
assert(testClientB
|
||||||
.encryption.olmManager.olmSessions[testClientA.identityKey].length ==
|
.encryption.olmManager.olmSessions[testClientA.identityKey].length ==
|
||||||
1);
|
1);
|
||||||
assert(testClientA
|
assert(testClientA.encryption.olmManager.olmSessions[testClientB.identityKey]
|
||||||
.encryption.olmManager.olmSessions[testClientB.identityKey].first
|
.first.sessionId ==
|
||||||
.session_id() ==
|
testClientB.encryption.olmManager.olmSessions[testClientA.identityKey]
|
||||||
testClientB
|
.first.sessionId);
|
||||||
.encryption.olmManager.olmSessions[testClientA.identityKey].first
|
|
||||||
.session_id());
|
|
||||||
assert(room.client.encryption.keyManager
|
assert(room.client.encryption.keyManager
|
||||||
.getOutboundGroupSession(room.id)
|
.getOutboundGroupSession(room.id)
|
||||||
.outboundGroupSession
|
.outboundGroupSession
|
||||||
|
|
Loading…
Reference in a new issue