refactor: Check server
This commit is contained in:
parent
343c26b3ed
commit
5381c3935c
31
README.md
31
README.md
|
@ -26,45 +26,38 @@ import 'package:famedlysdk/famedlysdk.dart';
|
||||||
2. Create a new client:
|
2. Create a new client:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
Client matrix = Client("HappyChat");
|
Client client = Client("HappyChat");
|
||||||
```
|
```
|
||||||
|
|
||||||
Take a look here for an example store:
|
Take a look here for an example store:
|
||||||
[https://gitlab.com/ChristianPauly/fluffychat-flutter/snippets](https://gitlab.com/ChristianPauly/fluffychat-flutter/snippets)
|
[https://gitlab.com/ChristianPauly/fluffychat-flutter/snippets](https://gitlab.com/ChristianPauly/fluffychat-flutter/snippets)
|
||||||
|
|
||||||
```dart
|
|
||||||
Client matrix = Client("HappyChat");
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Connect to a Matrix Homeserver and listen to the streams:
|
3. Connect to a Matrix Homeserver and listen to the streams:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
matrix.onLoginStateChanged.stream.listen((bool loginState){
|
client.onLoginStateChanged.stream.listen((bool loginState){
|
||||||
print("LoginState: ${loginState.toString()}");
|
print("LoginState: ${loginState.toString()}");
|
||||||
});
|
});
|
||||||
|
|
||||||
matrix.onEvent.stream.listen((EventUpdate eventUpdate){
|
client.onEvent.stream.listen((EventUpdate eventUpdate){
|
||||||
print("New event update!");
|
print("New event update!");
|
||||||
});
|
});
|
||||||
|
|
||||||
matrix.onRoomUpdate.stream.listen((RoomUpdate eventUpdate){
|
client.onRoomUpdate.stream.listen((RoomUpdate eventUpdate){
|
||||||
print("New room update!");
|
print("New room update!");
|
||||||
});
|
});
|
||||||
|
|
||||||
final bool serverValid = await matrix.checkServer("https://yourhomeserver.abc");
|
try {
|
||||||
|
await client.checkHomeserver("https://yourhomeserver.abc");
|
||||||
final bool loginValid = await matrix.login("username", "password");
|
await client.login("username", "password");
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
print('No luck...');
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Send a message to a Room:
|
4. Send a message to a Room:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
final resp = await matrix.jsonRequest(
|
await client.getRoomById('your_room_id').sendTextEvent('Hello world');
|
||||||
type: "PUT",
|
|
||||||
action: "/r0/rooms/!fjd823j:example.com/send/m.room.message/$txnId",
|
|
||||||
data: {
|
|
||||||
"msgtype": "m.text",
|
|
||||||
"body": "hello"
|
|
||||||
}
|
|
||||||
);
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -232,43 +232,51 @@ class Client extends MatrixApi {
|
||||||
return WellKnownInformations.fromJson(rawJson);
|
return WellKnownInformations.fromJson(rawJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks the supported versions of the Matrix protocol and the supported
|
@Deprecated('Use [checkHomeserver] instead.')
|
||||||
/// login types. Returns false if the server is not compatible with the
|
|
||||||
/// client.
|
|
||||||
/// Throws FormatException, TimeoutException and MatrixException on error.
|
|
||||||
Future<bool> checkServer(dynamic serverUrl) async {
|
Future<bool> checkServer(dynamic serverUrl) async {
|
||||||
try {
|
try {
|
||||||
if (serverUrl is Uri) {
|
await checkHomeserver(serverUrl);
|
||||||
homeserver = serverUrl;
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks the supported versions of the Matrix protocol and the supported
|
||||||
|
/// login types. Throws an exception if the server is not compatible with the
|
||||||
|
/// client and sets [homeserver] to [serverUrl] if it is. Supports the types [Uri]
|
||||||
|
/// and [String].
|
||||||
|
Future<void> checkHomeserver(dynamic homeserverUrl,
|
||||||
|
{Set<String> supportedLoginTypes = supportedLoginTypes}) async {
|
||||||
|
try {
|
||||||
|
if (homeserverUrl is Uri) {
|
||||||
|
homeserver = homeserverUrl;
|
||||||
} else {
|
} else {
|
||||||
// URLs allow to have whitespace surrounding them, see https://www.w3.org/TR/2011/WD-html5-20110525/urls.html
|
// 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
|
// 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.
|
// and thus can't let Uri.parse() deal with it.
|
||||||
serverUrl = serverUrl.trim();
|
homeserverUrl = homeserverUrl.trim();
|
||||||
// strip a trailing slash
|
// strip a trailing slash
|
||||||
if (serverUrl.endsWith('/')) {
|
if (homeserverUrl.endsWith('/')) {
|
||||||
serverUrl = serverUrl.substring(0, serverUrl.length - 1);
|
homeserverUrl = homeserverUrl.substring(0, homeserverUrl.length - 1);
|
||||||
}
|
}
|
||||||
homeserver = Uri.parse(serverUrl);
|
homeserver = Uri.parse(homeserverUrl);
|
||||||
}
|
}
|
||||||
final versions = await requestSupportedVersions();
|
final versions = await requestSupportedVersions();
|
||||||
|
|
||||||
for (var i = 0; i < versions.versions.length; i++) {
|
if (!versions.versions
|
||||||
if (versions.versions[i] == 'r0.5.0' ||
|
.any((version) => supportedVersions.contains(version))) {
|
||||||
versions.versions[i] == 'r0.6.0') {
|
throw Exception(
|
||||||
break;
|
'Server supports the versions: ${versions.versions.toString()} but this application is only compatible with ${supportedVersions.toString()}.');
|
||||||
} else if (i == versions.versions.length - 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final loginTypes = await requestLoginTypes();
|
final loginTypes = await requestLoginTypes();
|
||||||
if (loginTypes.flows.indexWhere((f) => f.type == 'm.login.password') ==
|
if (!loginTypes.flows.any((f) => supportedLoginTypes.contains(f.type))) {
|
||||||
-1) {
|
throw Exception(
|
||||||
return false;
|
'Server supports the Login Types: ${loginTypes.flows.map((f) => f.toJson).toList().toString()} but this application is only compatible with ${supportedLoginTypes.toString()}.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return;
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
homeserver = null;
|
homeserver = null;
|
||||||
rethrow;
|
rethrow;
|
||||||
|
@ -277,7 +285,7 @@ class Client extends MatrixApi {
|
||||||
|
|
||||||
/// Checks to see if a username is available, and valid, for the server.
|
/// Checks to see if a username is available, and valid, for the server.
|
||||||
/// Returns the fully-qualified Matrix user ID (MXID) that has been registered.
|
/// Returns the fully-qualified Matrix user ID (MXID) that has been registered.
|
||||||
/// You have to call [checkServer] first to set a homeserver.
|
/// You have to call [checkHomeserver] first to set a homeserver.
|
||||||
@override
|
@override
|
||||||
Future<LoginResponse> register({
|
Future<LoginResponse> register({
|
||||||
String username,
|
String username,
|
||||||
|
@ -315,7 +323,7 @@ class Client extends MatrixApi {
|
||||||
/// Handles the login and allows the client to call all APIs which require
|
/// Handles the login and allows the client to call all APIs which require
|
||||||
/// authentication. Returns false if the login was not successful. Throws
|
/// authentication. Returns false if the login was not successful. Throws
|
||||||
/// MatrixException if login was not successful.
|
/// MatrixException if login was not successful.
|
||||||
/// You have to call [checkServer] first to set a homeserver.
|
/// You have to call [checkHomeserver] first to set a homeserver.
|
||||||
@override
|
@override
|
||||||
Future<LoginResponse> login({
|
Future<LoginResponse> login({
|
||||||
String type = 'm.login.password',
|
String type = 'm.login.password',
|
||||||
|
@ -479,8 +487,11 @@ class Client extends MatrixApi {
|
||||||
? PushRuleSet.fromJson(accountData['m.push_rules'].content)
|
? PushRuleSet.fromJson(accountData['m.push_rules'].content)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
static String syncFilters = '{"room":{"state":{"lazy_load_members":true}}}';
|
static const Set<String> supportedVersions = {'r0.5.0', 'r0.6.0'};
|
||||||
static String messagesFilters = '{"lazy_load_members":true}';
|
static const Set<String> supportedLoginTypes = {'m.login.password'};
|
||||||
|
static const String syncFilters =
|
||||||
|
'{"room":{"state":{"lazy_load_members":true}}}';
|
||||||
|
static const String messagesFilters = '{"lazy_load_members":true}';
|
||||||
static const List<String> supportedDirectEncryptionAlgorithms = [
|
static const List<String> supportedDirectEncryptionAlgorithms = [
|
||||||
'm.olm.v1.curve25519-aes-sha2'
|
'm.olm.v1.curve25519-aes-sha2'
|
||||||
];
|
];
|
||||||
|
|
|
@ -77,11 +77,11 @@ void main() {
|
||||||
expect(matrix.homeserver, null);
|
expect(matrix.homeserver, null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await matrix.checkServer('https://fakeserver.wrongaddress');
|
await matrix.checkHomeserver('https://fakeserver.wrongaddress');
|
||||||
} on FormatException catch (exception) {
|
} on FormatException catch (exception) {
|
||||||
expect(exception != null, true);
|
expect(exception != null, true);
|
||||||
}
|
}
|
||||||
await matrix.checkServer('https://fakeserver.notexisting');
|
await matrix.checkHomeserver('https://fakeserver.notexisting');
|
||||||
expect(matrix.homeserver.toString(), 'https://fakeserver.notexisting');
|
expect(matrix.homeserver.toString(), 'https://fakeserver.notexisting');
|
||||||
|
|
||||||
final available = await matrix.usernameAvailable('testuser');
|
final available = await matrix.usernameAvailable('testuser');
|
||||||
|
@ -311,12 +311,11 @@ void main() {
|
||||||
|
|
||||||
roomUpdateListFuture = matrix.onRoomUpdate.stream.toList();
|
roomUpdateListFuture = matrix.onRoomUpdate.stream.toList();
|
||||||
eventUpdateListFuture = matrix.onEvent.stream.toList();
|
eventUpdateListFuture = matrix.onEvent.stream.toList();
|
||||||
final checkResp =
|
|
||||||
await matrix.checkServer('https://fakeServer.notExisting');
|
await matrix.checkHomeserver('https://fakeServer.notExisting');
|
||||||
|
|
||||||
final loginResp = await matrix.login(user: 'test', password: '1234');
|
final loginResp = await matrix.login(user: 'test', password: '1234');
|
||||||
|
|
||||||
expect(checkResp, true);
|
|
||||||
expect(loginResp != null, true);
|
expect(loginResp != null, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ void main() {
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
otherClient.database = client.database;
|
otherClient.database = client.database;
|
||||||
await otherClient.checkServer('https://fakeServer.notExisting');
|
await otherClient.checkHomeserver('https://fakeServer.notExisting');
|
||||||
otherClient.connect(
|
otherClient.connect(
|
||||||
newToken: 'abc',
|
newToken: 'abc',
|
||||||
newUserID: '@othertest:fakeServer.notExisting',
|
newUserID: '@othertest:fakeServer.notExisting',
|
||||||
|
|
|
@ -85,7 +85,7 @@ void main() {
|
||||||
client1 = await getClient();
|
client1 = await getClient();
|
||||||
client2 = Client('othertestclient', httpClient: FakeMatrixApi());
|
client2 = Client('othertestclient', httpClient: FakeMatrixApi());
|
||||||
client2.database = client1.database;
|
client2.database = client1.database;
|
||||||
await client2.checkServer('https://fakeServer.notExisting');
|
await client2.checkHomeserver('https://fakeServer.notExisting');
|
||||||
client2.connect(
|
client2.connect(
|
||||||
newToken: 'abc',
|
newToken: 'abc',
|
||||||
newUserID: '@othertest:fakeServer.notExisting',
|
newUserID: '@othertest:fakeServer.notExisting',
|
||||||
|
|
|
@ -264,7 +264,7 @@ void main() {
|
||||||
|
|
||||||
test('sendAgain', () async {
|
test('sendAgain', () async {
|
||||||
var matrix = Client('testclient', httpClient: FakeMatrixApi());
|
var matrix = Client('testclient', httpClient: FakeMatrixApi());
|
||||||
await matrix.checkServer('https://fakeServer.notExisting');
|
await matrix.checkHomeserver('https://fakeServer.notExisting');
|
||||||
await matrix.login(user: 'test', password: '1234');
|
await matrix.login(user: 'test', password: '1234');
|
||||||
|
|
||||||
var event = Event.fromJson(
|
var event = Event.fromJson(
|
||||||
|
@ -280,7 +280,7 @@ void main() {
|
||||||
|
|
||||||
test('requestKey', () async {
|
test('requestKey', () async {
|
||||||
var matrix = Client('testclient', httpClient: FakeMatrixApi());
|
var matrix = Client('testclient', httpClient: FakeMatrixApi());
|
||||||
await matrix.checkServer('https://fakeServer.notExisting');
|
await matrix.checkHomeserver('https://fakeServer.notExisting');
|
||||||
await matrix.login(user: 'test', password: '1234');
|
await matrix.login(user: 'test', password: '1234');
|
||||||
|
|
||||||
var event = Event.fromJson(
|
var event = Event.fromJson(
|
||||||
|
@ -990,7 +990,7 @@ void main() {
|
||||||
THUMBNAIL_BUFF,
|
THUMBNAIL_BUFF,
|
||||||
}[url];
|
}[url];
|
||||||
};
|
};
|
||||||
await client.checkServer('https://fakeServer.notExisting');
|
await client.checkHomeserver('https://fakeServer.notExisting');
|
||||||
final room = Room(id: '!localpart:server.abc', client: client);
|
final room = Room(id: '!localpart:server.abc', client: client);
|
||||||
var event = Event.fromJson({
|
var event = Event.fromJson({
|
||||||
'type': EventTypes.Message,
|
'type': EventTypes.Message,
|
||||||
|
@ -1133,7 +1133,7 @@ void main() {
|
||||||
FILE_BUFF,
|
FILE_BUFF,
|
||||||
}[url];
|
}[url];
|
||||||
};
|
};
|
||||||
await client.checkServer('https://fakeServer.notExisting');
|
await client.checkHomeserver('https://fakeServer.notExisting');
|
||||||
final room = Room(id: '!localpart:server.abc', client: await getClient());
|
final room = Room(id: '!localpart:server.abc', client: await getClient());
|
||||||
var event = Event.fromJson({
|
var event = Event.fromJson({
|
||||||
'type': EventTypes.Message,
|
'type': EventTypes.Message,
|
||||||
|
|
|
@ -31,7 +31,7 @@ const pickledOlmAccount =
|
||||||
Future<Client> getClient() async {
|
Future<Client> getClient() async {
|
||||||
final client = Client('testclient', httpClient: FakeMatrixApi());
|
final client = Client('testclient', httpClient: FakeMatrixApi());
|
||||||
client.database = getDatabase();
|
client.database = getDatabase();
|
||||||
await client.checkServer('https://fakeServer.notExisting');
|
await client.checkHomeserver('https://fakeServer.notExisting');
|
||||||
client.connect(
|
client.connect(
|
||||||
newToken: 'abcd',
|
newToken: 'abcd',
|
||||||
newUserID: '@test:fakeServer.notExisting',
|
newUserID: '@test:fakeServer.notExisting',
|
||||||
|
|
|
@ -27,7 +27,7 @@ void main() {
|
||||||
group('MxContent', () {
|
group('MxContent', () {
|
||||||
test('Formatting', () async {
|
test('Formatting', () async {
|
||||||
var client = Client('testclient', httpClient: FakeMatrixApi());
|
var client = Client('testclient', httpClient: FakeMatrixApi());
|
||||||
await client.checkServer('https://fakeserver.notexisting');
|
await client.checkHomeserver('https://fakeserver.notexisting');
|
||||||
final mxc = 'mxc://exampleserver.abc/abcdefghijklmn';
|
final mxc = 'mxc://exampleserver.abc/abcdefghijklmn';
|
||||||
final content = Uri.parse(mxc);
|
final content = Uri.parse(mxc);
|
||||||
expect(content.isScheme('mxc'), true);
|
expect(content.isScheme('mxc'), true);
|
||||||
|
|
|
@ -49,7 +49,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Create', () async {
|
test('Create', () async {
|
||||||
await client.checkServer('https://fakeServer.notExisting');
|
await client.checkHomeserver('https://fakeServer.notExisting');
|
||||||
|
|
||||||
client.onEvent.add(EventUpdate(
|
client.onEvent.add(EventUpdate(
|
||||||
type: EventUpdateType.timeline,
|
type: EventUpdateType.timeline,
|
||||||
|
|
|
@ -85,28 +85,28 @@ void main() {
|
||||||
user3.calcDisplayname(mxidLocalPartFallback: false), 'Unknown user');
|
user3.calcDisplayname(mxidLocalPartFallback: false), 'Unknown user');
|
||||||
});
|
});
|
||||||
test('kick', () async {
|
test('kick', () async {
|
||||||
await client.checkServer('https://fakeserver.notexisting');
|
await client.checkHomeserver('https://fakeserver.notexisting');
|
||||||
await user1.kick();
|
await user1.kick();
|
||||||
});
|
});
|
||||||
test('ban', () async {
|
test('ban', () async {
|
||||||
await client.checkServer('https://fakeserver.notexisting');
|
await client.checkHomeserver('https://fakeserver.notexisting');
|
||||||
await user1.ban();
|
await user1.ban();
|
||||||
});
|
});
|
||||||
test('unban', () async {
|
test('unban', () async {
|
||||||
await client.checkServer('https://fakeserver.notexisting');
|
await client.checkHomeserver('https://fakeserver.notexisting');
|
||||||
await user1.unban();
|
await user1.unban();
|
||||||
});
|
});
|
||||||
test('setPower', () async {
|
test('setPower', () async {
|
||||||
await client.checkServer('https://fakeserver.notexisting');
|
await client.checkHomeserver('https://fakeserver.notexisting');
|
||||||
await user1.setPower(50);
|
await user1.setPower(50);
|
||||||
});
|
});
|
||||||
test('startDirectChat', () async {
|
test('startDirectChat', () async {
|
||||||
await client.checkServer('https://fakeserver.notexisting');
|
await client.checkHomeserver('https://fakeserver.notexisting');
|
||||||
await client.login(user: 'test', password: '1234');
|
await client.login(user: 'test', password: '1234');
|
||||||
await user1.startDirectChat();
|
await user1.startDirectChat();
|
||||||
});
|
});
|
||||||
test('getPresence', () async {
|
test('getPresence', () async {
|
||||||
await client.checkServer('https://fakeserver.notexisting');
|
await client.checkHomeserver('https://fakeserver.notexisting');
|
||||||
await client.handleSync(SyncUpdate.fromJson({
|
await client.handleSync(SyncUpdate.fromJson({
|
||||||
'presence': {
|
'presence': {
|
||||||
'events': [
|
'events': [
|
||||||
|
@ -121,15 +121,15 @@ void main() {
|
||||||
expect(user1.presence.presence.presence, PresenceType.online);
|
expect(user1.presence.presence.presence, PresenceType.online);
|
||||||
});
|
});
|
||||||
test('canBan', () async {
|
test('canBan', () async {
|
||||||
await client.checkServer('https://fakeserver.notexisting');
|
await client.checkHomeserver('https://fakeserver.notexisting');
|
||||||
expect(user1.canBan, false);
|
expect(user1.canBan, false);
|
||||||
});
|
});
|
||||||
test('canKick', () async {
|
test('canKick', () async {
|
||||||
await client.checkServer('https://fakeserver.notexisting');
|
await client.checkHomeserver('https://fakeserver.notexisting');
|
||||||
expect(user1.canKick, false);
|
expect(user1.canKick, false);
|
||||||
});
|
});
|
||||||
test('canChangePowerLevel', () async {
|
test('canChangePowerLevel', () async {
|
||||||
await client.checkServer('https://fakeserver.notexisting');
|
await client.checkHomeserver('https://fakeserver.notexisting');
|
||||||
expect(user1.canChangePowerLevel, false);
|
expect(user1.canChangePowerLevel, false);
|
||||||
});
|
});
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
|
|
@ -24,7 +24,7 @@ void test() async {
|
||||||
Logs.success('++++ Login Alice at ++++');
|
Logs.success('++++ Login Alice at ++++');
|
||||||
testClientA = Client('TestClientA');
|
testClientA = Client('TestClientA');
|
||||||
testClientA.database = getDatabase();
|
testClientA.database = getDatabase();
|
||||||
await testClientA.checkServer(TestUser.homeserver);
|
await testClientA.checkHomeserver(TestUser.homeserver);
|
||||||
await testClientA.login(
|
await testClientA.login(
|
||||||
user: TestUser.username, password: TestUser.password);
|
user: TestUser.username, password: TestUser.password);
|
||||||
assert(testClientA.encryptionEnabled);
|
assert(testClientA.encryptionEnabled);
|
||||||
|
@ -32,7 +32,7 @@ void test() async {
|
||||||
Logs.success('++++ Login Bob ++++');
|
Logs.success('++++ Login Bob ++++');
|
||||||
testClientB = Client('TestClientB');
|
testClientB = Client('TestClientB');
|
||||||
testClientB.database = getDatabase();
|
testClientB.database = getDatabase();
|
||||||
await testClientB.checkServer(TestUser.homeserver);
|
await testClientB.checkHomeserver(TestUser.homeserver);
|
||||||
await testClientB.login(
|
await testClientB.login(
|
||||||
user: TestUser.username2, password: TestUser.password);
|
user: TestUser.username2, password: TestUser.password);
|
||||||
assert(testClientB.encryptionEnabled);
|
assert(testClientB.encryptionEnabled);
|
||||||
|
@ -222,7 +222,7 @@ void test() async {
|
||||||
|
|
||||||
Logs.success('++++ Login Bob in another client ++++');
|
Logs.success('++++ Login Bob in another client ++++');
|
||||||
var testClientC = Client('TestClientC', database: getDatabase());
|
var testClientC = Client('TestClientC', database: getDatabase());
|
||||||
await testClientC.checkServer(TestUser.homeserver);
|
await testClientC.checkHomeserver(TestUser.homeserver);
|
||||||
await testClientC.login(
|
await testClientC.login(
|
||||||
user: TestUser.username2, password: TestUser.password);
|
user: TestUser.username2, password: TestUser.password);
|
||||||
await Future.delayed(Duration(seconds: 3));
|
await Future.delayed(Duration(seconds: 3));
|
||||||
|
|
Loading…
Reference in a new issue