chore: matrix_api_lite 0.4.0
This commit is contained in:
parent
bc2dac2ecc
commit
8665f092f4
|
|
@ -44,7 +44,8 @@ class KeyManager {
|
|||
final keyObj = olm.PkDecryption();
|
||||
try {
|
||||
final info = await getRoomKeysBackupInfo(false);
|
||||
if (info.algorithm != RoomKeysAlgorithmType.v1Curve25519AesSha2) {
|
||||
if (info.algorithm !=
|
||||
BackupAlgorithm.mMegolmBackupV1Curve25519AesSha2) {
|
||||
return false;
|
||||
}
|
||||
return keyObj.init_with_private_key(base64.decode(secret)) ==
|
||||
|
|
@ -523,9 +524,9 @@ class KeyManager {
|
|||
return (await encryption.ssss.getCached(megolmKey)) != null;
|
||||
}
|
||||
|
||||
RoomKeysVersionResponse _roomKeysVersionCache;
|
||||
GetRoomKeysVersionCurrentResponse _roomKeysVersionCache;
|
||||
DateTime _roomKeysVersionCacheDate;
|
||||
Future<RoomKeysVersionResponse> getRoomKeysBackupInfo(
|
||||
Future<GetRoomKeysVersionCurrentResponse> getRoomKeysBackupInfo(
|
||||
[bool useCache = true]) async {
|
||||
if (_roomKeysVersionCache != null &&
|
||||
_roomKeysVersionCacheDate != null &&
|
||||
|
|
@ -535,7 +536,7 @@ class KeyManager {
|
|||
.isBefore(_roomKeysVersionCacheDate)) {
|
||||
return _roomKeysVersionCache;
|
||||
}
|
||||
_roomKeysVersionCache = await client.getRoomKeysBackup();
|
||||
_roomKeysVersionCache = await client.getRoomKeysVersionCurrent();
|
||||
_roomKeysVersionCacheDate = DateTime.now();
|
||||
return _roomKeysVersionCache;
|
||||
}
|
||||
|
|
@ -553,7 +554,7 @@ class KeyManager {
|
|||
backupPubKey = decryption.init_with_private_key(privateKey);
|
||||
|
||||
if (backupPubKey == null ||
|
||||
info.algorithm != RoomKeysAlgorithmType.v1Curve25519AesSha2 ||
|
||||
info.algorithm != BackupAlgorithm.mMegolmBackupV1Curve25519AesSha2 ||
|
||||
info.authData['public_key'] != backupPubKey) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -706,7 +707,8 @@ class KeyManager {
|
|||
backupPubKey = decryption.init_with_private_key(privateKey);
|
||||
|
||||
if (backupPubKey == null ||
|
||||
info.algorithm != RoomKeysAlgorithmType.v1Curve25519AesSha2 ||
|
||||
info.algorithm !=
|
||||
BackupAlgorithm.mMegolmBackupV1Curve25519AesSha2 ||
|
||||
info.authData['public_key'] != backupPubKey) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -737,7 +739,7 @@ class KeyManager {
|
|||
_generateUploadKeys, args);
|
||||
Logs().i('[Key Manager] Uploading ${dbSessions.length} room keys...');
|
||||
// upload the payload...
|
||||
await client.storeRoomKeys(info.version, roomKeys);
|
||||
await client.postRoomKeysKey(info.version, roomKeys);
|
||||
// and now finally mark all the keys as uploaded
|
||||
// no need to optimze this, as we only run it so seldomly and almost never with many keys at once
|
||||
for (final dbSession in dbSessions) {
|
||||
|
|
@ -1011,7 +1013,7 @@ RoomKeys _generateUploadKeys(_GenerateUploadKeysArgs args) {
|
|||
try {
|
||||
enc.set_recipient_key(args.pubkey);
|
||||
// first we generate the payload to upload all the session keys in this chunk
|
||||
final roomKeys = RoomKeys();
|
||||
final roomKeys = RoomKeys(rooms: {});
|
||||
for (final dbSession in args.dbSessions) {
|
||||
final sess = SessionKey.fromDb(dbSession.dbSession, args.userId);
|
||||
if (!sess.isValid) {
|
||||
|
|
@ -1019,7 +1021,7 @@ RoomKeys _generateUploadKeys(_GenerateUploadKeysArgs args) {
|
|||
}
|
||||
// create the room if it doesn't exist
|
||||
if (!roomKeys.rooms.containsKey(sess.roomId)) {
|
||||
roomKeys.rooms[sess.roomId] = RoomKeysRoom();
|
||||
roomKeys.rooms[sess.roomId] = RoomKeyBackup(sessions: {});
|
||||
}
|
||||
// generate the encrypted content
|
||||
final payload = <String, dynamic>{
|
||||
|
|
@ -1035,7 +1037,7 @@ RoomKeys _generateUploadKeys(_GenerateUploadKeysArgs args) {
|
|||
// fetch the device, if available...
|
||||
//final device = args.client.getUserDeviceKeysByCurve25519Key(sess.senderKey);
|
||||
// aaaand finally add the session key to our payload
|
||||
roomKeys.rooms[sess.roomId].sessions[sess.sessionId] = RoomKeysSingleKey(
|
||||
roomKeys.rooms[sess.roomId].sessions[sess.sessionId] = KeyBackupData(
|
||||
firstMessageIndex: sess.inboundGroupSession.first_known_index(),
|
||||
forwardedCount: sess.forwardingCurve25519KeyChain.length,
|
||||
isVerified: dbSession.verified, //device?.verified ?? false,
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ import 'package:matrix/matrix.dart';
|
|||
import 'package:olm/olm.dart' as olm;
|
||||
|
||||
import '../encryption/utils/json_signature_check_extension.dart';
|
||||
import '../src/utils/run_in_root.dart';
|
||||
import 'encryption.dart';
|
||||
import 'utils/olm_session.dart';
|
||||
import '../src/utils/run_in_root.dart';
|
||||
|
||||
class OlmManager {
|
||||
final Encryption encryption;
|
||||
|
|
@ -264,7 +264,7 @@ class OlmManager {
|
|||
// and generate and upload more if not.
|
||||
|
||||
// If the server did not send us a count, assume it is 0
|
||||
final keyCount = countJson?.tryGet<int>('signed_curve25519', 0) ?? 0;
|
||||
final keyCount = countJson?.tryGet<int>('signed_curve25519') ?? 0;
|
||||
|
||||
// If the server does not support fallback keys, it will not tell us about them.
|
||||
// If the server supports them but has no key, upload a new one.
|
||||
|
|
@ -644,7 +644,7 @@ class OlmManager {
|
|||
return;
|
||||
}
|
||||
final device = client.getUserDeviceKeysByCurve25519Key(
|
||||
event.encryptedContent.tryGet<String>('sender_key', ''));
|
||||
event.encryptedContent.tryGet<String>('sender_key') ?? '');
|
||||
if (device == null) {
|
||||
return; // device not found
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'dart:core';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:core';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:base58check/base58.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
|
|
@ -51,11 +51,13 @@ const pbkdf2SaltLength = 64;
|
|||
/// https://matrix.org/docs/guides/implementing-more-advanced-e-2-ee-features-such-as-cross-signing#3-implementing-ssss
|
||||
class SSSS {
|
||||
final Encryption encryption;
|
||||
|
||||
Client get client => encryption.client;
|
||||
final pendingShareRequests = <String, _ShareRequest>{};
|
||||
final _validators = <String, FutureOr<bool> Function(String)>{};
|
||||
final _cacheCallbacks = <String, FutureOr<void> Function(String)>{};
|
||||
final Map<String, SSSSCache> _cache = <String, SSSSCache>{};
|
||||
|
||||
SSSS(this.encryption);
|
||||
|
||||
// for testing
|
||||
|
|
@ -174,7 +176,7 @@ class SSSS {
|
|||
await client.setAccountData(
|
||||
client.userID,
|
||||
EventTypes.SecretStorageDefaultKey,
|
||||
(SecretStorageDefaultKeyContent()..key = keyId).toJson(),
|
||||
SecretStorageDefaultKeyContent(key: keyId).toJson(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -193,13 +195,12 @@ class SSSS {
|
|||
final content = SecretStorageKeyContent();
|
||||
if (passphrase != null) {
|
||||
// we need to derive the key off of the passphrase
|
||||
content.passphrase = PassphraseInfo();
|
||||
content.passphrase.algorithm = AlgorithmTypes.pbkdf2;
|
||||
content.passphrase.salt = base64
|
||||
.encode(uc.secureRandomBytes(pbkdf2SaltLength)); // generate salt
|
||||
content.passphrase.iterations = pbkdf2DefaultIterations;
|
||||
;
|
||||
content.passphrase.bits = ssssKeyLength * 8;
|
||||
content.passphrase = PassphraseInfo(
|
||||
iterations: pbkdf2DefaultIterations,
|
||||
salt: base64.encode(uc.secureRandomBytes(pbkdf2SaltLength)),
|
||||
algorithm: AlgorithmTypes.pbkdf2,
|
||||
bits: ssssKeyLength * 8,
|
||||
);
|
||||
privateKey = await client
|
||||
.runInBackground(
|
||||
_keyFromPassphrase,
|
||||
|
|
@ -431,6 +432,7 @@ class SSSS {
|
|||
|
||||
DateTime _lastCacheRequest;
|
||||
bool _isPeriodicallyRequestingMissingCache = false;
|
||||
|
||||
Future<void> periodicallyRequestMissingCache() async {
|
||||
if (_isPeriodicallyRequestingMissingCache ||
|
||||
(_lastCacheRequest != null &&
|
||||
|
|
@ -606,10 +608,13 @@ class OpenSSSS {
|
|||
final SSSS ssss;
|
||||
final String keyId;
|
||||
final SecretStorageKeyContent keyData;
|
||||
|
||||
OpenSSSS({this.ssss, this.keyId, this.keyData});
|
||||
|
||||
Uint8List privateKey;
|
||||
|
||||
bool get isUnlocked => privateKey != null;
|
||||
|
||||
bool get hasPassphrase => keyData.passphrase != null;
|
||||
|
||||
String get recoveryKey =>
|
||||
|
|
@ -708,6 +713,7 @@ class OpenSSSS {
|
|||
class _KeyFromPassphraseArgs {
|
||||
final String passphrase;
|
||||
final PassphraseInfo info;
|
||||
|
||||
_KeyFromPassphraseArgs({this.passphrase, this.info});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -563,8 +563,8 @@ class Bootstrap {
|
|||
keyObj.free();
|
||||
}
|
||||
Logs().v('Create the new backup version...');
|
||||
await client.createRoomKeysBackup(
|
||||
RoomKeysAlgorithmType.v1Curve25519AesSha2,
|
||||
await client.postRoomKeysVersion(
|
||||
BackupAlgorithm.mMegolmBackupV1Curve25519AesSha2,
|
||||
<String, dynamic>{
|
||||
'public_key': pubKey,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import 'dart:convert';
|
|||
import 'dart:core';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:matrix/src/utils/run_in_root.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:matrix/src/utils/run_in_root.dart';
|
||||
import 'package:olm/olm.dart' as olm;
|
||||
|
||||
import '../encryption.dart';
|
||||
|
|
@ -44,6 +44,12 @@ typedef RoomSorter = int Function(Room a, Room b);
|
|||
|
||||
enum LoginState { logged, loggedOut }
|
||||
|
||||
extension TrailingSlash on Uri {
|
||||
Uri stripTrailingSlash() => path.endsWith('/')
|
||||
? replace(path: path.substring(0, path.length - 1))
|
||||
: this;
|
||||
}
|
||||
|
||||
/// Represents a Matrix client to communicate with a
|
||||
/// [Matrix](https://matrix.org) homeserver and is the entry point for this
|
||||
/// SDK.
|
||||
|
|
@ -163,7 +169,8 @@ class Client extends MatrixApi {
|
|||
room: RoomFilter(
|
||||
state: StateFilter(lazyLoadMembers: true),
|
||||
),
|
||||
) {
|
||||
),
|
||||
super(httpClient: httpClient) {
|
||||
supportedLoginTypes ??= {AuthenticationTypes.password};
|
||||
verificationMethods ??= <KeyVerificationMethod>{};
|
||||
importantStateEvents ??= {};
|
||||
|
|
@ -182,7 +189,6 @@ class Client extends MatrixApi {
|
|||
EventTypes.Encrypted,
|
||||
EventTypes.Sticker,
|
||||
]);
|
||||
this.httpClient = httpClient ?? http.Client();
|
||||
|
||||
// register all the default commands
|
||||
registerDefaultCommands();
|
||||
|
|
@ -308,7 +314,7 @@ class Client extends MatrixApi {
|
|||
}
|
||||
|
||||
/// Gets discovery information about the domain. The file may include additional keys.
|
||||
Future<WellKnownInformation> getWellKnownInformationsByUserId(
|
||||
Future<DiscoveryInformation> getDiscoveryInformationsByUserId(
|
||||
String MatrixIdOrDomain,
|
||||
) async {
|
||||
try {
|
||||
|
|
@ -321,15 +327,14 @@ class Client extends MatrixApi {
|
|||
// No-OP
|
||||
}
|
||||
final rawJson = json.decode(respBody);
|
||||
return WellKnownInformation.fromJson(rawJson);
|
||||
return DiscoveryInformation.fromJson(rawJson);
|
||||
} catch (_) {
|
||||
// we got an error processing or fetching the well-known information, let's
|
||||
// provide a reasonable fallback.
|
||||
return WellKnownInformation.fromJson(<String, dynamic>{
|
||||
'm.homeserver': <String, dynamic>{
|
||||
'base_url': Uri.https(MatrixIdOrDomain.domain, '').toString(),
|
||||
},
|
||||
});
|
||||
return DiscoveryInformation(
|
||||
mHomeserver: HomeserverInformation(
|
||||
baseUrl: Uri.https(MatrixIdOrDomain.domain, '')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -347,35 +352,19 @@ class Client extends MatrixApi {
|
|||
/// login types. Throws an exception if the server is not compatible with the
|
||||
/// client and sets [homeserver] to [homeserverUrl] if it is. Supports the
|
||||
/// types `Uri` and `String`.
|
||||
Future<WellKnownInformation> checkHomeserver(dynamic homeserverUrl,
|
||||
Future<DiscoveryInformation> checkHomeserver(dynamic homeserverUrl,
|
||||
{bool checkWellKnown = true}) async {
|
||||
try {
|
||||
if (homeserverUrl is Uri) {
|
||||
homeserver = homeserverUrl;
|
||||
} else {
|
||||
// URLs allow to have whitespace surrounding them, see https://www.w3.org/TR/2011/WD-html5-20110525/urls.html
|
||||
// As we want to strip a trailing slash, though, we have to trim the url ourself
|
||||
// and thus can't let Uri.parse() deal with it.
|
||||
homeserverUrl = homeserverUrl.trim();
|
||||
// strip a trailing slash
|
||||
if (homeserverUrl.endsWith('/')) {
|
||||
homeserverUrl = homeserverUrl.substring(0, homeserverUrl.length - 1);
|
||||
}
|
||||
homeserver = Uri.parse(homeserverUrl);
|
||||
}
|
||||
homeserver =
|
||||
(homeserverUrl is Uri) ? homeserverUrl : Uri.parse(homeserverUrl);
|
||||
homeserver = homeserver.stripTrailingSlash();
|
||||
|
||||
// Look up well known
|
||||
WellKnownInformation wellKnown;
|
||||
DiscoveryInformation wellKnown;
|
||||
if (checkWellKnown) {
|
||||
try {
|
||||
wellKnown = await getWellknown();
|
||||
homeserverUrl = wellKnown.mHomeserver.baseUrl.trim();
|
||||
// strip a trailing slash
|
||||
if (homeserverUrl.endsWith('/')) {
|
||||
homeserverUrl =
|
||||
homeserverUrl.substring(0, homeserverUrl.length - 1);
|
||||
}
|
||||
homeserver = Uri.parse(homeserverUrl);
|
||||
homeserver = wellKnown.mHomeserver.baseUrl.stripTrailingSlash();
|
||||
} catch (e) {
|
||||
Logs().v('Found no well known information', e);
|
||||
}
|
||||
|
|
@ -390,9 +379,9 @@ class Client extends MatrixApi {
|
|||
}
|
||||
|
||||
final loginTypes = await getLoginFlows();
|
||||
if (!loginTypes.flows.any((f) => supportedLoginTypes.contains(f.type))) {
|
||||
if (!loginTypes.any((f) => supportedLoginTypes.contains(f.type))) {
|
||||
throw BadServerLoginTypesException(
|
||||
loginTypes.flows.map((f) => f.type).toSet(), supportedLoginTypes);
|
||||
loginTypes.map((f) => f.type).toSet(), supportedLoginTypes);
|
||||
}
|
||||
|
||||
return wellKnown;
|
||||
|
|
@ -406,14 +395,14 @@ class Client extends MatrixApi {
|
|||
/// Returns the fully-qualified Matrix user ID (MXID) that has been registered.
|
||||
/// You have to call [checkHomeserver] first to set a homeserver.
|
||||
@override
|
||||
Future<LoginResponse> register({
|
||||
Future<RegisterResponse> register({
|
||||
String username,
|
||||
String password,
|
||||
String deviceId,
|
||||
String initialDeviceDisplayName,
|
||||
bool inhibitLogin,
|
||||
AuthenticationData auth,
|
||||
String kind,
|
||||
AccountKind kind,
|
||||
}) async {
|
||||
final response = await super.register(
|
||||
username: username,
|
||||
|
|
@ -447,8 +436,8 @@ class Client extends MatrixApi {
|
|||
/// Maybe you want to set [user] to the same String to stay compatible with
|
||||
/// older server versions.
|
||||
@override
|
||||
Future<LoginResponse> login({
|
||||
String type = AuthenticationTypes.password,
|
||||
Future<LoginResponse> login(
|
||||
LoginType type, {
|
||||
AuthenticationIdentifier identifier,
|
||||
String password,
|
||||
String token,
|
||||
|
|
@ -463,13 +452,12 @@ class Client extends MatrixApi {
|
|||
await checkHomeserver(user.domain);
|
||||
}
|
||||
final loginResp = await super.login(
|
||||
type: type,
|
||||
type,
|
||||
identifier: identifier,
|
||||
password: password,
|
||||
token: token,
|
||||
deviceId: deviceId,
|
||||
initialDeviceDisplayName: initialDeviceDisplayName,
|
||||
auth: auth,
|
||||
// ignore: deprecated_member_use
|
||||
user: user,
|
||||
// ignore: deprecated_member_use
|
||||
|
|
@ -553,7 +541,7 @@ class Client extends MatrixApi {
|
|||
roomId = await createRoom(
|
||||
invite: [mxid],
|
||||
isDirect: true,
|
||||
preset: CreateRoomPreset.trusted_private_chat,
|
||||
preset: CreateRoomPreset.trustedPrivateChat,
|
||||
);
|
||||
|
||||
if (roomId == null) return roomId;
|
||||
|
|
@ -576,7 +564,7 @@ class Client extends MatrixApi {
|
|||
Visibility visibility = Visibility.public,
|
||||
String spaceAliasName,
|
||||
List<String> invite,
|
||||
List<Map<String, dynamic>> invite3pid,
|
||||
List<Invite3pid> invite3pid,
|
||||
String roomVersion,
|
||||
}) =>
|
||||
createRoom(
|
||||
|
|
@ -607,7 +595,7 @@ class Client extends MatrixApi {
|
|||
return getProfileFromUserId(userID);
|
||||
}
|
||||
|
||||
final Map<String, Profile> _profileCache = {};
|
||||
final Map<String, ProfileInformation> _profileCache = {};
|
||||
|
||||
/// Get the combined profile information for this user.
|
||||
/// If [getFromRooms] is true then the profile will first be searched from the
|
||||
|
|
@ -629,15 +617,25 @@ class Client extends MatrixApi {
|
|||
if (room != null) {
|
||||
final user =
|
||||
room.getParticipants().firstWhere((User user) => user.id == userId);
|
||||
return Profile(user.displayName, user.avatarUrl);
|
||||
return Profile(
|
||||
userId: userId,
|
||||
displayName: user.displayName,
|
||||
avatarUrl: user.avatarUrl);
|
||||
}
|
||||
}
|
||||
if (cache && _profileCache.containsKey(userId)) {
|
||||
return _profileCache[userId];
|
||||
final profile = _profileCache[userId];
|
||||
return Profile(
|
||||
userId: userId,
|
||||
displayName: profile.displayname,
|
||||
avatarUrl: profile.avatarUrl);
|
||||
}
|
||||
final profile = await getUserProfile(userId);
|
||||
_profileCache[userId] = profile;
|
||||
return profile;
|
||||
return Profile(
|
||||
userId: userId,
|
||||
displayName: profile.displayname,
|
||||
avatarUrl: profile.avatarUrl);
|
||||
}
|
||||
|
||||
Future<List<Room>> get archive async {
|
||||
|
|
@ -685,10 +683,10 @@ class Client extends MatrixApi {
|
|||
/// Uploads a file and automatically caches it in the database, if it is small enough
|
||||
/// and returns the mxc url as a string.
|
||||
@override
|
||||
Future<String> uploadContent(Uint8List file, String fileName,
|
||||
{String contentType}) async {
|
||||
final mxc =
|
||||
await super.uploadContent(file, fileName, contentType: contentType);
|
||||
Future<String> uploadContent(Uint8List file,
|
||||
{String filename, String contentType}) async {
|
||||
final mxc = await super
|
||||
.uploadContent(file, filename: filename, contentType: contentType);
|
||||
final storeable = database != null && file.length <= database.maxFileSize;
|
||||
if (storeable) {
|
||||
await database.storeFile(
|
||||
|
|
@ -715,7 +713,7 @@ class Client extends MatrixApi {
|
|||
|
||||
/// Uploads a new user avatar for this user.
|
||||
Future<void> setAvatar(MatrixFile file) async {
|
||||
final uploadResp = await uploadContent(file.bytes, file.name);
|
||||
final uploadResp = await uploadContent(file.bytes, filename: file.name);
|
||||
await setAvatarUrl(userID, Uri.parse(uploadResp));
|
||||
return;
|
||||
}
|
||||
|
|
@ -2006,16 +2004,16 @@ sort order of ${prevState.sortOrder}. This should never happen...''');
|
|||
/// Changes the password. You should either set oldPasswort or another authentication flow.
|
||||
@override
|
||||
Future<void> changePassword(String newPassword,
|
||||
{String oldPassword, AuthenticationData auth}) async {
|
||||
{String oldPassword, AuthenticationData auth, bool logoutDevices}) async {
|
||||
try {
|
||||
if (oldPassword != null) {
|
||||
auth = AuthenticationPassword(
|
||||
user: userID,
|
||||
identifier: AuthenticationUserIdentifier(user: userID),
|
||||
password: oldPassword,
|
||||
);
|
||||
}
|
||||
await super.changePassword(newPassword, auth: auth);
|
||||
await super.changePassword(newPassword,
|
||||
auth: auth, logoutDevices: logoutDevices);
|
||||
} on MatrixException catch (matrixException) {
|
||||
if (!matrixException.requireAdditionalAuthentication) {
|
||||
rethrow;
|
||||
|
|
@ -2031,11 +2029,11 @@ sort order of ${prevState.sortOrder}. This should never happen...''');
|
|||
return changePassword(
|
||||
newPassword,
|
||||
auth: AuthenticationPassword(
|
||||
user: userID,
|
||||
identifier: AuthenticationUserIdentifier(user: userID),
|
||||
password: oldPassword,
|
||||
session: matrixException.session,
|
||||
),
|
||||
logoutDevices: logoutDevices,
|
||||
);
|
||||
} catch (_) {
|
||||
rethrow;
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:matrix/src/utils/space_child.dart';
|
||||
import 'package:html_unescape/html_unescape.dart';
|
||||
import 'package:matrix/src/utils/space_child.dart';
|
||||
|
||||
import '../matrix.dart';
|
||||
import 'client.dart';
|
||||
|
|
@ -288,7 +288,7 @@ class Room {
|
|||
if (!aliases.contains(canonicalAlias)) {
|
||||
await client.setRoomAlias(canonicalAlias, id);
|
||||
}
|
||||
await client.setRoomStateWithKey(id, EventTypes.RoomCanonicalAlias, {
|
||||
await client.setRoomStateWithKey(id, EventTypes.RoomCanonicalAlias, '', {
|
||||
'alias': canonicalAlias,
|
||||
});
|
||||
}
|
||||
|
|
@ -455,6 +455,7 @@ class Room {
|
|||
Future<String> setName(String newName) => client.setRoomStateWithKey(
|
||||
id,
|
||||
EventTypes.RoomName,
|
||||
'',
|
||||
{'name': newName},
|
||||
);
|
||||
|
||||
|
|
@ -462,6 +463,7 @@ class Room {
|
|||
Future<String> setDescription(String newName) => client.setRoomStateWithKey(
|
||||
id,
|
||||
EventTypes.RoomTopic,
|
||||
'',
|
||||
{'topic': newName},
|
||||
);
|
||||
|
||||
|
|
@ -506,14 +508,15 @@ class Room {
|
|||
/// this works if there is no connection to the homeserver.
|
||||
Future<void> setUnread(bool unread) async {
|
||||
final content = MarkedUnread(unread).toJson();
|
||||
await _handleFakeSync(SyncUpdate()
|
||||
await _handleFakeSync(SyncUpdate(nextBatch: '')
|
||||
..rooms = (RoomsUpdate()
|
||||
..join = (({}..[id] = (JoinedRoomUpdate()
|
||||
..accountData = [
|
||||
BasicRoomEvent()
|
||||
..content = content
|
||||
..roomId = id
|
||||
..type = EventType.markedUnread
|
||||
BasicRoomEvent(
|
||||
content: content,
|
||||
roomId: id,
|
||||
type: EventType.markedUnread,
|
||||
)
|
||||
])))));
|
||||
await client.setAccountDataPerRoom(
|
||||
client.userID,
|
||||
|
|
@ -524,23 +527,24 @@ class Room {
|
|||
if (unread == false && lastEvent != null) {
|
||||
await setReadMarker(
|
||||
lastEvent.eventId,
|
||||
readReceiptLocationEventId: lastEvent.eventId,
|
||||
mRead: lastEvent.eventId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if this room has a m.favourite tag.
|
||||
bool get isFavourite => tags[TagType.Favourite] != null;
|
||||
bool get isFavourite => tags[TagType.favourite] != null;
|
||||
|
||||
/// Sets the m.favourite tag for this room.
|
||||
Future<void> setFavourite(bool favourite) =>
|
||||
favourite ? addTag(TagType.Favourite) : removeTag(TagType.Favourite);
|
||||
favourite ? addTag(TagType.favourite) : removeTag(TagType.favourite);
|
||||
|
||||
/// Call the Matrix API to change the pinned events of this room.
|
||||
Future<String> setPinnedEvents(List<String> pinnedEventIds) =>
|
||||
client.setRoomStateWithKey(
|
||||
id,
|
||||
EventTypes.RoomPinnedEvents,
|
||||
'',
|
||||
{'pinned': pinnedEventIds},
|
||||
);
|
||||
|
||||
|
|
@ -635,13 +639,13 @@ class Room {
|
|||
}
|
||||
final uploadResp = await client.uploadContent(
|
||||
uploadFile.bytes,
|
||||
uploadFile.name,
|
||||
filename: uploadFile.name,
|
||||
contentType: uploadFile.mimeType,
|
||||
);
|
||||
final thumbnailUploadResp = uploadThumbnail != null
|
||||
? await client.uploadContent(
|
||||
uploadThumbnail.bytes,
|
||||
uploadThumbnail.name,
|
||||
filename: uploadThumbnail.name,
|
||||
contentType: uploadThumbnail.mimeType,
|
||||
)
|
||||
: null;
|
||||
|
|
@ -751,17 +755,16 @@ class Room {
|
|||
RegExp(r'<mx-reply>.*<\/mx-reply>',
|
||||
caseSensitive: false, multiLine: false, dotAll: true),
|
||||
'');
|
||||
final repliedHtml = content.tryGet<String>(
|
||||
'formatted_body',
|
||||
final repliedHtml = content.tryGet<String>('formatted_body') ??
|
||||
htmlEscape
|
||||
.convert(content.tryGet<String>('body', ''))
|
||||
.replaceAll('\n', '<br>'));
|
||||
.convert(content.tryGet<String>('body') ?? '')
|
||||
.replaceAll('\n', '<br>');
|
||||
content['formatted_body'] =
|
||||
'<mx-reply><blockquote><a href="https://matrix.to/#/${inReplyTo.room.id}/${inReplyTo.eventId}">In reply to</a> <a href="https://matrix.to/#/${inReplyTo.senderId}">${inReplyTo.senderId}</a><br>$replyHtml</blockquote></mx-reply>$repliedHtml';
|
||||
// We escape all @room-mentions here to prevent accidental room pings when an admin
|
||||
// replies to a message containing that!
|
||||
content['body'] =
|
||||
'${replyText.replaceAll('@room', '@\u200broom')}\n\n${content.tryGet<String>('body', '')}';
|
||||
'${replyText.replaceAll('@room', '@\u200broom')}\n\n${content.tryGet<String>('body') ?? ''}';
|
||||
content['m.relates_to'] = {
|
||||
'm.in_reply_to': {
|
||||
'event_id': inReplyTo.eventId,
|
||||
|
|
@ -783,21 +786,22 @@ class Room {
|
|||
}
|
||||
}
|
||||
final sentDate = DateTime.now();
|
||||
final syncUpdate = SyncUpdate()
|
||||
final syncUpdate = SyncUpdate(nextBatch: '')
|
||||
..rooms = (RoomsUpdate()
|
||||
..join = (<String, JoinedRoomUpdate>{}..[id] = (JoinedRoomUpdate()
|
||||
..timeline = (TimelineUpdate()
|
||||
..events = [
|
||||
MatrixEvent()
|
||||
..content = content
|
||||
..type = type
|
||||
..eventId = messageID
|
||||
..senderId = client.userID
|
||||
..originServerTs = sentDate
|
||||
..unsigned = {
|
||||
MatrixEvent(
|
||||
content: content,
|
||||
type: type,
|
||||
eventId: messageID,
|
||||
senderId: client.userID,
|
||||
originServerTs: sentDate,
|
||||
unsigned: {
|
||||
messageSendingStatusKey: 0,
|
||||
'transaction_id': messageID,
|
||||
},
|
||||
)
|
||||
]))));
|
||||
await _handleFakeSync(syncUpdate);
|
||||
|
||||
|
|
@ -868,7 +872,7 @@ class Room {
|
|||
if ([MatrixError.M_NOT_FOUND, MatrixError.M_UNKNOWN]
|
||||
.contains(exception.error)) {
|
||||
await _handleFakeSync(
|
||||
SyncUpdate()
|
||||
SyncUpdate(nextBatch: '')
|
||||
..rooms = (RoomsUpdate()
|
||||
..leave = {
|
||||
'$id': (LeftRoomUpdate()),
|
||||
|
|
@ -909,12 +913,13 @@ class Room {
|
|||
return await client.setRoomStateWithKey(
|
||||
id,
|
||||
EventTypes.RoomPowerLevels,
|
||||
'',
|
||||
powerMap,
|
||||
);
|
||||
}
|
||||
|
||||
/// Call the Matrix API to invite a user to this room.
|
||||
Future<void> invite(String userID) => client.inviteToRoom(id, userID);
|
||||
Future<void> invite(String userID) => client.inviteUser(id, userID);
|
||||
|
||||
/// Request more previous events from the server. [historyCount] defines how much events should
|
||||
/// be received maximum. When the request is answered, [onHistoryReceived] will be triggered **before**
|
||||
|
|
@ -936,7 +941,7 @@ class Room {
|
|||
if (!((resp.chunk?.isNotEmpty ?? false) && resp.end != null)) return;
|
||||
|
||||
await client.handleSync(
|
||||
SyncUpdate()
|
||||
SyncUpdate(nextBatch: '')
|
||||
..rooms = (RoomsUpdate()
|
||||
..join = ({}..[id] = (JoinedRoomUpdate()
|
||||
..state = resp.state
|
||||
|
|
@ -1000,16 +1005,15 @@ class Room {
|
|||
|
||||
/// Sets the position of the read marker for a given room, and optionally the
|
||||
/// read receipt's location.
|
||||
Future<void> setReadMarker(String eventId,
|
||||
{String readReceiptLocationEventId}) async {
|
||||
if (readReceiptLocationEventId != null) {
|
||||
Future<void> setReadMarker(String eventId, {String mRead}) async {
|
||||
if (mRead != null) {
|
||||
notificationCount = 0;
|
||||
await client.database?.resetNotificationCount(client.id, id);
|
||||
}
|
||||
await client.setReadMarker(
|
||||
id,
|
||||
eventId,
|
||||
readReceiptLocationEventId: readReceiptLocationEventId,
|
||||
mRead: mRead,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1021,7 +1025,9 @@ class Room {
|
|||
await client.database?.resetNotificationCount(client.id, id);
|
||||
await client.postReceipt(
|
||||
id,
|
||||
ReceiptType.mRead,
|
||||
eventId,
|
||||
{},
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1034,7 +1040,7 @@ class Room {
|
|||
await client.setReadMarker(
|
||||
id,
|
||||
eventID,
|
||||
readReceiptLocationEventId: eventID,
|
||||
mRead: eventID,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1294,10 +1300,12 @@ class Room {
|
|||
/// Uploads a new user avatar for this room. Returns the event ID of the new
|
||||
/// m.room.avatar event.
|
||||
Future<String> setAvatar(MatrixFile file) async {
|
||||
final uploadResp = await client.uploadContent(file.bytes, file.name);
|
||||
final uploadResp =
|
||||
await client.uploadContent(file.bytes, filename: file.name);
|
||||
return await client.setRoomStateWithKey(
|
||||
id,
|
||||
EventTypes.RoomAvatar,
|
||||
'',
|
||||
{'url': uploadResp},
|
||||
);
|
||||
}
|
||||
|
|
@ -1402,14 +1410,14 @@ class Room {
|
|||
'global',
|
||||
PushRuleKind.room,
|
||||
id,
|
||||
[PushRuleAction.dont_notify],
|
||||
[PushRuleAction.dontNotify],
|
||||
);
|
||||
} else if (pushRuleState == PushRuleState.notify) {
|
||||
await client.setPushRule(
|
||||
'global',
|
||||
PushRuleKind.room,
|
||||
id,
|
||||
[PushRuleAction.dont_notify],
|
||||
[PushRuleAction.dontNotify],
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
|
@ -1422,9 +1430,9 @@ class Room {
|
|||
'global',
|
||||
PushRuleKind.override,
|
||||
id,
|
||||
[PushRuleAction.dont_notify],
|
||||
[PushRuleAction.dontNotify],
|
||||
conditions: [
|
||||
PushConditions('event_match', key: 'room_id', pattern: id)
|
||||
PushCondition(kind: 'event_match', key: 'room_id', pattern: id)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
@ -1578,6 +1586,7 @@ class Room {
|
|||
await client.setRoomStateWithKey(
|
||||
id,
|
||||
EventTypes.RoomJoinRules,
|
||||
'',
|
||||
{
|
||||
'join_rule': joinRules.toString().replaceAll('JoinRules.', ''),
|
||||
},
|
||||
|
|
@ -1600,6 +1609,7 @@ class Room {
|
|||
await client.setRoomStateWithKey(
|
||||
id,
|
||||
EventTypes.GuestAccess,
|
||||
'',
|
||||
{
|
||||
'guest_access': _guestAccessMap[guestAccess],
|
||||
},
|
||||
|
|
@ -1623,6 +1633,7 @@ class Room {
|
|||
await client.setRoomStateWithKey(
|
||||
id,
|
||||
EventTypes.HistoryVisibility,
|
||||
'',
|
||||
{
|
||||
'history_visibility': _historyVisibilityMap[historyVisibility],
|
||||
},
|
||||
|
|
@ -1648,6 +1659,7 @@ class Room {
|
|||
await client.setRoomStateWithKey(
|
||||
id,
|
||||
EventTypes.Encryption,
|
||||
'',
|
||||
{
|
||||
'algorithm': algorithm,
|
||||
},
|
||||
|
|
@ -1742,22 +1754,14 @@ class Room {
|
|||
}) async {
|
||||
if (!isSpace) throw Exception('Room is not a space!');
|
||||
via ??= [roomId.domain];
|
||||
await client.setRoomStateWithKey(
|
||||
id,
|
||||
EventTypes.spaceChild,
|
||||
{
|
||||
await client.setRoomStateWithKey(id, EventTypes.spaceChild, roomId, {
|
||||
'via': via,
|
||||
if (order != null) 'order': order,
|
||||
if (suggested != null) 'suggested': suggested,
|
||||
},
|
||||
roomId);
|
||||
await client.setRoomStateWithKey(
|
||||
roomId,
|
||||
EventTypes.spaceParent,
|
||||
{
|
||||
});
|
||||
await client.setRoomStateWithKey(roomId, EventTypes.spaceParent, id, {
|
||||
'via': via,
|
||||
},
|
||||
id);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -172,8 +172,8 @@ extension CommandsClientExtension on Client {
|
|||
return await args.room.client.setRoomStateWithKey(
|
||||
args.room.id,
|
||||
EventTypes.RoomMember,
|
||||
currentEventJson,
|
||||
args.room.client.userID,
|
||||
currentEventJson,
|
||||
);
|
||||
});
|
||||
addCommand('myroomavatar', (CommandArgs args) async {
|
||||
|
|
@ -185,8 +185,8 @@ extension CommandsClientExtension on Client {
|
|||
return await args.room.client.setRoomStateWithKey(
|
||||
args.room.id,
|
||||
EventTypes.RoomMember,
|
||||
currentEventJson,
|
||||
args.room.client.userID,
|
||||
currentEventJson,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import 'package:matrix/matrix.dart';
|
|||
import 'package:olm/olm.dart' as olm;
|
||||
|
||||
import '../../encryption.dart';
|
||||
|
||||
import '../client.dart';
|
||||
import '../event.dart';
|
||||
import '../room.dart';
|
||||
|
|
@ -132,12 +131,22 @@ class DeviceKeysList {
|
|||
DeviceKeysList(this.userId, this.client);
|
||||
}
|
||||
|
||||
class SimpleSignableKey extends MatrixSignableKey {
|
||||
@override
|
||||
String identifier;
|
||||
|
||||
SimpleSignableKey.fromJson(Map<String, dynamic> json) : super.fromJson(json);
|
||||
}
|
||||
|
||||
abstract class SignableKey extends MatrixSignableKey {
|
||||
Client client;
|
||||
Map<String, dynamic> validSignatures;
|
||||
bool _verified;
|
||||
bool blocked;
|
||||
|
||||
@override
|
||||
String identifier;
|
||||
|
||||
String get ed25519Key => keys['ed25519:$identifier'];
|
||||
bool get verified => (directVerified || crossVerified) && !blocked;
|
||||
bool get encryptToDevice =>
|
||||
|
|
@ -161,8 +170,8 @@ abstract class SignableKey extends MatrixSignableKey {
|
|||
blocked = false;
|
||||
}
|
||||
|
||||
MatrixSignableKey cloneForSigning() {
|
||||
final newKey = MatrixSignableKey.fromJson(toJson().copy());
|
||||
SimpleSignableKey cloneForSigning() {
|
||||
final newKey = SimpleSignableKey.fromJson(toJson().copy());
|
||||
newKey.identifier = identifier;
|
||||
newKey.signatures ??= <String, Map<String, String>>{};
|
||||
newKey.signatures.clear();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class SpaceChild {
|
|||
: assert(state.type == EventTypes.spaceChild),
|
||||
roomId = state.stateKey,
|
||||
via = state.content.tryGetList<String>('via'),
|
||||
order = state.content.tryGet<String>('order', ''),
|
||||
order = state.content.tryGet<String>('order') ?? '',
|
||||
suggested = state.content.tryGet<bool>('suggested');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ class UiaRequest<T> {
|
|||
Map<String, dynamic> params = <String, dynamic>{};
|
||||
|
||||
UiaRequestState get state => _state;
|
||||
|
||||
set state(UiaRequestState newState) {
|
||||
if (_state == newState) return;
|
||||
_state = newState;
|
||||
|
|
@ -57,7 +58,8 @@ class UiaRequest<T> {
|
|||
Future<T> _run([AuthenticationData auth]) async {
|
||||
state = UiaRequestState.loading;
|
||||
try {
|
||||
auth ??= AuthenticationData(session: session);
|
||||
auth ??=
|
||||
AuthenticationData(session: session, type: AuthenticationTypes.token);
|
||||
final res = await request(auth);
|
||||
state = UiaRequestState.done;
|
||||
result = res;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ dependencies:
|
|||
crypto: ^3.0.0
|
||||
base58check: ^2.0.0
|
||||
olm: ^2.0.0
|
||||
matrix_api_lite: ^0.3.5
|
||||
matrix_api_lite: ^0.4.0
|
||||
hive: ^2.0.4
|
||||
ffi: ^1.0.0
|
||||
js: ^0.6.3
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ void main() {
|
|||
|
||||
try {
|
||||
await matrix.checkHomeserver('https://fakeserver.wrongaddress');
|
||||
} on MatrixConnectionException catch (exception) {
|
||||
} catch (exception) {
|
||||
expect(exception != null, true);
|
||||
}
|
||||
await matrix.checkHomeserver('https://fakeserver.notexisting',
|
||||
|
|
@ -323,7 +323,7 @@ void main() {
|
|||
await matrix.checkHomeserver('https://fakeserver.notexisting',
|
||||
checkWellKnown: false);
|
||||
|
||||
final loginResp = await matrix.login(
|
||||
final loginResp = await matrix.login(LoginType.mLoginPassword,
|
||||
identifier: AuthenticationUserIdentifier(user: 'test'),
|
||||
password: '1234');
|
||||
|
||||
|
|
@ -368,12 +368,12 @@ void main() {
|
|||
final profile = await matrix.getProfileFromUserId('@getme:example.com',
|
||||
getFromRooms: false);
|
||||
expect(profile.avatarUrl.toString(), 'mxc://test');
|
||||
expect(profile.displayname, 'You got me');
|
||||
expect(profile.displayName, 'You got me');
|
||||
final aliceProfile =
|
||||
await matrix.getProfileFromUserId('@alice:example.com');
|
||||
expect(aliceProfile.avatarUrl.toString(),
|
||||
'mxc://example.org/SEsfnsuifSDFSSEF');
|
||||
expect(aliceProfile.displayname, 'Alice Margatroid');
|
||||
expect(aliceProfile.displayName, 'Alice Margatroid');
|
||||
});
|
||||
test('sendToDeviceEncrypted', () async {
|
||||
if (!olmEnabled) {
|
||||
|
|
@ -642,7 +642,8 @@ void main() {
|
|||
});
|
||||
test('upload', () async {
|
||||
final client = await getClient();
|
||||
final response = await client.uploadContent(Uint8List(0), 'file.jpeg');
|
||||
final response =
|
||||
await client.uploadContent(Uint8List(0), filename: 'file.jpeg');
|
||||
expect(response, 'mxc://example.com/AQwafuaFswefuhsfAFAgsw');
|
||||
expect(await client.database.getFile(response) != null,
|
||||
client.database.supportsFileStoring);
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ void main() {
|
|||
final matrix = Client('testclient', httpClient: FakeMatrixApi());
|
||||
await matrix.checkHomeserver('https://fakeserver.notexisting',
|
||||
checkWellKnown: false);
|
||||
await matrix.login(
|
||||
await matrix.login(LoginType.mLoginPassword,
|
||||
identifier: AuthenticationUserIdentifier(user: 'test'),
|
||||
password: '1234');
|
||||
|
||||
|
|
@ -288,7 +288,7 @@ void main() {
|
|||
final matrix = Client('testclient', httpClient: FakeMatrixApi());
|
||||
await matrix.checkHomeserver('https://fakeserver.notexisting',
|
||||
checkWellKnown: false);
|
||||
await matrix.login(
|
||||
await matrix.login(LoginType.mLoginPassword,
|
||||
identifier: AuthenticationUserIdentifier(user: 'test'),
|
||||
password: '1234');
|
||||
|
||||
|
|
|
|||
|
|
@ -16,15 +16,14 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:matrix/matrix.dart' as sdk;
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:core';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:http/http.dart';
|
||||
import 'package:http/testing.dart';
|
||||
import 'package:matrix/matrix.dart' as sdk;
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
Map<String, dynamic> decodeJson(dynamic data) {
|
||||
if (data is String) {
|
||||
|
|
@ -122,11 +121,9 @@ class FakeMatrixApi extends MockClient {
|
|||
action.contains('/account_data/') &&
|
||||
!action.contains('/room/')) {
|
||||
final type = Uri.decodeComponent(action.split('/').last);
|
||||
final syncUpdate = sdk.SyncUpdate()
|
||||
final syncUpdate = sdk.SyncUpdate(nextBatch: '')
|
||||
..accountData = [
|
||||
sdk.BasicEvent()
|
||||
..content = decodeJson(data)
|
||||
..type = type
|
||||
sdk.BasicEvent(content: decodeJson(data), type: type)
|
||||
];
|
||||
if (client.database != null) {
|
||||
await client.database.transaction(() async {
|
||||
|
|
@ -2111,7 +2108,7 @@ class FakeMatrixApi extends MockClient {
|
|||
}
|
||||
}
|
||||
// and generate a fake sync
|
||||
client.handleSync(sdk.SyncUpdate());
|
||||
client.handleSync(sdk.SyncUpdate(nextBatch: ''));
|
||||
}
|
||||
return {};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -648,8 +648,8 @@ void main() {
|
|||
});
|
||||
|
||||
test('Test tag methods', () async {
|
||||
await room.addTag(TagType.Favourite, order: 0.1);
|
||||
await room.removeTag(TagType.Favourite);
|
||||
await room.addTag(TagType.favourite, order: 0.1);
|
||||
await room.removeTag(TagType.favourite);
|
||||
expect(room.isFavourite, false);
|
||||
room.roomAccountData['m.tag'] = BasicRoomEvent.fromJson({
|
||||
'content': {
|
||||
|
|
@ -661,7 +661,7 @@ void main() {
|
|||
'type': 'm.tag'
|
||||
});
|
||||
expect(room.tags.length, 1);
|
||||
expect(room.tags[TagType.Favourite].order, 0.1);
|
||||
expect(room.tags[TagType.favourite].order, 0.1);
|
||||
expect(room.isFavourite, true);
|
||||
await room.setFavourite(false);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ void main() {
|
|||
setUp(() async {
|
||||
await client.checkHomeserver('https://fakeserver.notexisting',
|
||||
checkWellKnown: false);
|
||||
await client.login(
|
||||
await client.login(LoginType.mLoginPassword,
|
||||
identifier: AuthenticationUserIdentifier(user: 'test'),
|
||||
password: '1234');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ void test() async {
|
|||
Logs().i('++++ Login Alice at ++++');
|
||||
testClientA = Client('TestClientA', databaseBuilder: getDatabase);
|
||||
await testClientA.checkHomeserver(TestUser.homeserver);
|
||||
await testClientA.login(
|
||||
await testClientA.login(LoginType.mLoginPassword,
|
||||
identifier: AuthenticationUserIdentifier(user: TestUser.username),
|
||||
password: TestUser.password);
|
||||
assert(testClientA.encryptionEnabled);
|
||||
|
|
@ -30,7 +30,7 @@ void test() async {
|
|||
Logs().i('++++ Login Bob ++++');
|
||||
testClientB = Client('TestClientB', databaseBuilder: getDatabase);
|
||||
await testClientB.checkHomeserver(TestUser.homeserver);
|
||||
await testClientB.login(
|
||||
await testClientB.login(LoginType.mLoginPassword,
|
||||
identifier: AuthenticationUserIdentifier(user: TestUser.username2),
|
||||
password: TestUser.password);
|
||||
assert(testClientB.encryptionEnabled);
|
||||
|
|
@ -220,7 +220,7 @@ void test() async {
|
|||
Logs().i('++++ Login Bob in another client ++++');
|
||||
var testClientC = Client('TestClientC', databaseBuilder: getDatabase);
|
||||
await testClientC.checkHomeserver(TestUser.homeserver);
|
||||
await testClientC.login(
|
||||
await testClientC.login(LoginType.mLoginPassword,
|
||||
identifier: AuthenticationUserIdentifier(user: TestUser.username2),
|
||||
password: TestUser.password);
|
||||
await Future.delayed(Duration(seconds: 3));
|
||||
|
|
|
|||
Loading…
Reference in New Issue